Kaizen #84 - PHP SDK [Part I]

Kaizen #84 - PHP SDK [Part I]

Hello and welcome to another Kaizen week!

In this week's post, we'll show you how to get started with Zoho CRM's PHP SDK, and walk you through the configuration and initialization process.

PHP Software Development Kit

PHP SDK allows you to create client PHP applications that can be integrated with Zoho CRM effortlessly. It serves as a wrapper for the REST APIs, thus making it easier to use the services of Zoho CRM.

Why PHP SDK?

Easy authentication: You don't have to worry about manually managing authentication because the PHP SDK takes care of generating access/refresh tokens for you.
Easy and Efficient data exchange: With the PHP SDK, you can easily exchange data between Zoho CRM and your client PHP application, where the CRM entities are modelled as classes. You can declare and define CRM API equivalents as simple functions in your PHP application.

Prerequisites 

  • The client app must have PHP 7 or above with a cURL extension. cURL extension is used to connect and communicate with the Zoho CRM APIs.
  • The client app must have the PHP SDK installed through Composer

How to start using the PHP SDK?

  1. Prerequisite : Register your application with Zoho CRM.
  2. Install the PHP SDK.
  3. Knowledge Base : Token Persistence
  4. Configuration 
  5. initialization.

1. Register your application with Zoho CRM

Registering your application with Zoho CRM is a mandatory step in order to authenticate and authorize API calls using the OAuth2.0 standards.
  1. Go to https://api-console.zoho.com
  2. Click on Get Started or +ADD CLIENT.
  3. Choose the Client Type.
  4. Fill in the necessary details and click CREATE. Once you successfully register your self-client, you will receive a Client ID and Client Secret.

2. Install PHP SDK 

1. Install Composer, if not already installed. Please check the corresponding link for installation instructions.

2. Install PHP-SDK using Composer
  • Navigate to the workspace of your client app.
  • Run the following command in the workspace. Upon successful installation, the system will create a package named vendor in the workspace of your client app.   Note : This command installs SDK for API v2.1.

    composer require zohocrm/php-sdk-2.1

3. To use the SDK in your project, add the following line in your project PHP files. This loads and includes our PHP-SDK library in your project. If you skip this step, you will get a fatal error in response due to the missing libraries.

require 'vendor/autoload.php';

3. Token Persistence

Token persistence refers to storing and utilizing authentication tokens provided by Zoho, enabling the SDK to refresh the access tokens without the need for user intervention. The SDK offers three types of persistence - File, DB, and Custom - with file persistence being the default method. 
The persistence is achieved by writing an implementation of the inbuilt TokenStore interface, which has the following callback methods. 

Method
Description
getToken($user, $token)
Invoked before firing a request to fetch the saved tokens. This method returns an implementation of Token interface object for the library to process it.
saveToken($user, $token)
Invoked after fetching access and refresh tokens from Zoho. This method saves the token details.
deleteToken($token)
This method is used to delete the given token details.
getTokens()
This method is used to retrieve all the stored tokens.
deleteTokens() 
The method to delete all the stored tokens.
getTokenById($id, $token) 
This method is used to retrieve the user token details based on the unique ID.

a. Token Persistence using a Database

Database persistence is a technique that involves storing and retrieving data from a database. If you prefer using database persistence, you can use MySQL. 
Create a table in your database with the required columns. For example, if you want to persist your tokens in a table named token in database named zoho, use the following:
CREATE DATABASE zoho; // use this to create database named zoho
// use this to create a table named token, with the necessary columns
CREATE TABLE token ( 
  id varchar(255) NOT NULL,
  user_mail varchar(255) NOT NULL,
  client_id varchar(255),
  client_secret varchar(255),
  refresh_token varchar(255),
  access_token varchar(255),
  grant_token varchar(255),
  expiry_time varchar(20),
  redirect_url varchar(255),
  primary key (id)
);

In this example, your tokens will be persisted in the token table in your zoho database.

b. File Persistence

File Persistence allows storing and retrieving the authentication tokens from the given file path. The file contains id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and redirect_url. 

c. Custom Persistence

Custom Persistence refers to a technique where users can create their own method of storing and retrieving authentication tokens. To use this method, users need to implement the TokenStore interface and override its methods according to their own logic.

4. Configuration

Configuration is a critical step in which you set up SDK's configuration details like user authentication, token persistence, logging and API call timeout settings, and more. Listed below are the keys that you define in this step.

Key
Description
user
mandatory
Represents the mail id, which is used to identify and fetch tokens from the File or DB.
environment
mandatory
Represents the data centre details in Domain::Environment pattern.
Domains : USDataCenter, EUDataCenter, INDataCenter, CNDataCenter, AUDataCenter
Environments : PRODUCTION(), DEVELOPER(), SANDBOX()
token
mandatory
Contains user token details. Depending on the tokens, you can choose grantToken flow, refreshToken flow or accessToken flow.
logger
optional
Contains the configuration for logging exceptions and API call information. By default, the logs will be available in the workspace as sdk_logs.log.
store
optional
Contains details for the Token Persistence object. You can choose between DB Store, File Store or Custom Store, and configure accordingly.
SDKConfig
optional
Contains additional configuration details like timeout, autorefresh fields, picklistvalidation, etc
requestProxy
optional
Contains the details of the proxy, if you are using a proxy server to authenticate and make the API calls.
resourcePath
optional
The path containing the absolute directory path to store user specific files containing the module fields information.


Let us discuss how to configure each of them, in detail.
a. user : The user key will be used to store and identify the tokenstore details in the DB or File Storage for token persistence. Create an instance of UserSignature that identifies the current user with the following :
  1. $user = new UserSignature("patricia@zoho.com");
b. environment : The API environment which decides the domain and the URL to make API calls. 
  1. $environment = USDataCenter::PRODUCTION();
c. token : Create an instance of OAuthToken with the information that you get after registering your Zoho client. Depending on the tokens available with you, you can choose one of the following flows. 
Note : You need to generate the tokens (grant/access/refresh) beforehand. 
  • grantToken flow - You should use the grant Token for configuration.
    $token = (new OAuthBuilder())
      ->clientId("clientId")
      ->clientSecret("clientSecret")
      ->grantToken("grantToken")
      ->redirectURL("redirectURL")
      ->build();

  • refreshToken flow -In this flow, use the refresh token.
    $token = (new OAuthBuilder())
      ->clientId("clientId")
      ->clientSecret("clientSecret")
      ->refreshToken("refreshToken")
      ->redirectURL("redirectURL")
      ->build();

  • accessToken flow - You can use the access token to configure in this flow. Please note that the token will not be persisted in this case, and the access token will be directly used to make the API calls.

    $token = (new OAuthBuilder()
      ->accessToken("accessToken")
      ->build(); 

d. logger : Create an instance of Logger Class to log exception and API information. You can set the level you want to log (FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, ALL, OFF), and also configure the file path and file name for the log file.

$logger = (new LogBuilder())
->level(Levels::INFO)
->filePath("/Documents/php_sdk_log.log")
->build();

e. store : Configure your token persistence using this method. If this is skipped, the SDK creates the sdk_tokens.txt in the current working directory to persist the tokens by default.
  • DB Store - Configure the Database details, where you want to store your tokens.
    $tokenstore = (new DBBuilder())
    ->host("hostName")
    ->databaseName("dataBaseName")
    ->userName("userName")
    ->password("password")
    ->portNumber("portNumber")
    ->tableName("tableName")
    ->build();

  • File store - Give the absolute file path, where you want to store the tokens. 
    $tokenstore = new FileStore("absolute_file_path");

  • Custom Store - In this method, you can implement your own method for storing and retrieving the tokens. Please note that to do so, you must implement the TokenStore interface, and override its callback methods (getToken, saveToken, deleteToken, getTokens, deleteTokens, getTokenById). 
    $tokenstore = new CustomStore();

Note :  The corresponding storage will  have id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and redirect_url. The id is a unique system generated key.

f. SDKConfig : The additional SDK configurations are taken care of with this method. 

Configuration Key
Description
autoRefreshFields
Default Value : False
A boolean configuration key to enable or disable automatic refreshing of module fields in the background. If set to true, fields are refreshed every hour, and if set to false, fields must be manually refreshed or deleted.
pickListValidation
Default Value : True
This field enables or disables pick list validation. If enabled, user input for pick list fields is validated, and if the value does not exist in the pick list, the SDK throws an error. If disabled, the input is not validated and the API call is made.
enableSSLVerification
Default Value : True
A boolean field to enable or disable curl certificate verification. If set to true, the SDK verifies the authenticity of certificate. If set to false, the SDK skips the verification.
connectionTimeout
Default Value : 0
The maximum time (in seconds) to wait while trying to connect. Use 0 to wait indefinitely.
timeout
Default Value : 0
The maximum time (in seconds) to allow cURL functions to execute. Use 0 to wait indefinitely.
  1. $autoRefreshFields = false;
  2. $pickListValidation = false;
  3. $enableSSLVerification = true;
  4. $connectionTimeout = 2;
  5. $timeout = 2;
  6. $sdkConfig = (new SDKConfigBuilder())
  7. ->autoRefreshFields($autoRefreshFields)
  8. ->pickListValidation($pickListValidation)
  9. ->sslVerification($enableSSLVerification)
  10. ->connectionTimeout($connectionTimeout)
  11. ->timeout($timeout)
  12. ->build();
g. requestProxy : Create an instance of RequestProxy containing the proxy properties of the user. Configure this only if you're using a proxy server to make the API calls.

$requestProxy = (new ProxyBuilder())
 ->host("proxyHost")
 ->port("proxyPort")
 ->user("proxyUser")
 ->password("password")
 ->build();

h. resourcePath : Configure path containing the absolute directory path to store user specific files containing module fields information.

$resourcePath = "/Documents/phpsdk-application";

5. Initilization

Once you have completed the configuration process, you can move on to initializing the SDK and begin making API requests.

Here is a sample code to initialize the SDK, using refresh token flow and DB Persistence.

<?php
use com\zoho\api\authenticator\OAuthBuilder;
use com\zoho\api\authenticator\store\DBBuilder;
use com\zoho\api\authenticator\store\FileStore;
use com\zoho\crm\api\InitializeBuilder;
use com\zoho\crm\api\UserSignature;
use com\zoho\crm\api\dc\USDataCenter;
use com\zoho\api\logger\LogBuilder;
use com\zoho\api\logger\Levels;
use com\zoho\crm\api\SDKConfigBuilder;
use com\zoho\crm\api\ProxyBuilder;
use com\zoho\api\authenticator\store\DBBuilder;

require_once "vendor/autoload.php";

class Initialize
{
  public static function initialize()
  {
    $user = new UserSignature("patricia@zoho.com");
    $environment = USDataCenter::PRODUCTION();
    $token = (new OAuthBuilder())
    ->clientId("1000.xxxxxxxxxxxxxxxx")
    ->clientSecret("554a9776d10ff016a92c1eb01xxxxxxxxxx")
    ->refreshToken("1000.xxxxxxxxxxxxxxxxxxxx")
    ->redirectURL("www.zoho.com")
    ->build();
    $logger = (new LogBuilder())
    ->level(Levels::INFO)
    ->filePath("/Documents/php_sdk_log.log")
    ->build();
   $tokenstore = (new DBBuilder())
    ->host("insert_your_hostname_here")
    ->databaseName("insert_your_database_name_here")
    ->userName("insert_your_db_username_here")
    ->password("insert_your_db_password_here")
    ->portNumber("insert_your_portnumber_here")
    ->tableName("insert_your_table_name_here")
    ->build();
    $autoRefreshFields = false;
    $pickListValidation = false;
    $connectionTimeout = 2;
    $timeout = 2;
    $sdkConfig = (new SDKConfigBuilder())
    ->autoRefreshFields($autoRefreshFields)
    ->pickListValidation($pickListValidation)
    ->sslVerification($enableSSLVerification)
    ->connectionTimeout($connectionTimeout)
    ->timeout($timeout)
    ->build();
    $resourcePath = "/Documents/phpsdk-application";
    $requestProxy = (new ProxyBuilder())
    ->host("proxyHost")
    ->port("proxyPort")
    ->user("proxyUser")
    ->password("password")
    ->build();
    (new InitializeBuilder())
    ->user($user)
    ->environment($environment)
    ->token($token)
    ->store($tokenstore)
    ->SDKConfig($configInstance)
    ->resourcePath($resourcePath)
    ->logger($logger)
    ->requestProxy($requestProxy)
    ->initialize();
  }
}
?>


You are now all set to explore the functionalities of SDK. Here is a sample code to get the records from Leads module, with the ifmodifiedsince header.

<?php
use com\zoho\api\authenticator\OAuthBuilder;
use com\zoho\crm\api\dc\USDataCenter;
use com\zoho\crm\api\InitializeBuilder;
use com\zoho\crm\api\UserSignature;
use com\zoho\crm\api\record\RecordOperations;
use com\zoho\crm\api\record\GetRecordsHeader;
use com\zoho\crm\api\HeaderMap;
use com\zoho\crm\api\ParameterMap;
require_once "vendor/autoload.php";

class Record
{
    public static function initialize()
    {
        $user = new UserSignature('myname@mydomain.com');
        $environment = USDataCenter::PRODUCTION();
        $token = (new OAuthBuilder())
        ->clientId("1000.xxxxxxx")
        ->clientSecret("4b5baxxxxxxxxxxxxf")
        ->grantToken("1000.xxxxx")
        ->build();
        (new InitializeBuilder())
            ->user($user)
            ->environment($environment)
            ->token($token)
            ->initialize();
    }

    public static function getRecords()
    {
        $recordOperations = new RecordOperations();
        $paramInstance = new ParameterMap();
        $headerInstance = new HeaderMap();
     $ifmodifiedsince = date_create("2022-06-01T12:00:00+05:30")->setTimezone(new \DateTimeZone(date_default_timezone_get()));
        $headerInstance->add(GetRecordsHeader::IfModifiedSince(), $ifmodifiedsince);
        $response = $recordOperations->getRecords("Leads", $paramInstance, $headerInstance);
        echo($response->getStatusCode() . "\n");
        print_r($response);
    }
}
Record::initialize();
Record::getRecords();


Next week, we will dive deeper and provide more sample codes to help you further. Stay tuned!

If you have any queries, let us know the comments below, or drop an email to support@zohocrm.com. We would love to hear from you. 



    • Recent Topics

    • Automate insurance document workflows with Zoho Writer

      Insurance companies have to deal with creating and managing complex documents and forms, such as policy applications, explanation of benefits documents, brochures, renewals, and claim forms. Handling all of this manually is hugely time and effort intensive,
    • Create PDFs with Text so that we can copy from a generated PDF

      Currently, any information that a user enters into a field cannot be highlighted and copied from the PDF that Zoho Sign renders. For example, if someone were to provide a phone number in a Zoho Sign text field, you would not be able to copy the phone
    • How To Insert Data into Zoho Table using Api

      Hi Community, I have created a table inside zoho tables. How do I insert data into table using API. Please tell the exact endpoint and payload , I just have to insert data into table columns. Also tell how to find tableid, viewid, baseid etc. which are
    • How do I delete a folder in Marketing Automation?

      Folders are used across contact lists and segments, and email templates. How do I delete a folder once it's been created?
    • Portal Approval Process

      Hi Zoho team and fellow users, I am seeking a method to establish a multi-step approval process between a Zoho user and a portal user (Custom Portal) to review and approve requests through the Custom Portal. For instance, within this setup, one of the
    • Narrative 8: Intelligent in-app support that's instantly available anytime and anywhere

      Behind the scenes of a successful ticketing system - BTS Series Narrative 8: Intelligent in-app support that's instantly available anytime and anywhere The App Support Across Platforms (ASAP) add-on for Zoho Desk is an independent application that integrates
    • Navigation issue — unable to return to Customer page after opening Receipt from Transactions

      Steps to reproduce: Open a Customer record. Go to Transactions tab and open a Receipt by clicking its receipt number. After viewing the receipt, clicking browser Back or closing the receipt does not reliably return me to the original Customer record (I
    • Thermal Printer Option Needed for Delivery Challan Templates

      Currently in Zoho Books, the Delivery Challan template only supports A4 and A5 page sizes. However, in many businesses (especially retail and hardware), we use thermal printers (like 3-inch or 4-inch rolls) to print delivery challans. It would be very
    • Separate Default Payment Modes for Receipts vs. Payments

      Right now, when I set a default Payment Mode via a customer invoice or Payments Received screen, that same mode shows up for vendor payments (Purchases → Payments Made). 🔹 Request: We need different default modes for: Customer receipts (e.g., default
    • Update/Change GSTIN in GST Settings of zohobooks

      We are trying to update our GSTIN under the GST settings section of our Zohobooks account Initially, we had entered a dummy GSTIN (123456789123456) to generate a sample invoice before obtaining our official GST registration. After receiving our actual
    • Link Payment Mode and Paid Through Accounts

      For most users, it's very difficult for them to understand that the Payment Mode is totally independent of the Paid Through account when paying bills. It seems (and is) redundant for them to have to select what is basically the same thing twice. The current
    • Lets enable business to choose the default payment mode

      Lets enable business to choose the default payment mode so that we do not have choose payment mode again and again for each and every transsctions
    • Add Attachment Support to Zoho Flow Mailhook / Email Trigger Module

      Dear Zoho Support Team, We hope you are well. We would like to kindly request a feature enhancement for the Mailhook module in Zoho Flow. Currently, the email trigger in Zoho Flow provides access to the message body, subject, from address, and to address,
    • South African Payment Gateways

      Since the "Demise" of Wave many South African users have moved over to Zoho and yet for years users have been requesting Integration with a South African Payment Gateway to no avail. Payfast was the most commonly requested gateway as it supports recurring
    • Has anyone verified if Zoho is PCI compliant?

      We are planning on using Zoho to process payments via Authorize.net. We have everything set up and are attempting to complete the PCI DSS SAQ-A requirement for our merchant account. This requires us to prove Zoho has completed the SAQ-D for Service Providers. We need a way to verify compliance, or a copy of an attestation of compliance signed by the appropriate officer at Zoho. I assume I'm not the first person to use Zoho to process payment, and therefore not the first to require this information
    • Bigin Plugin for Outlook

      Could we get this added? The Gmail version already exists, and I would like to avoid having to make a switch.
    • Date does not fit the field

      Hi There. I am having fun learning zoho sign API. Today I noticed the "Signed Date" field does not fit, or alternatively the font is to large for the auto field space. See screenshot below. The signed date field is created by putting {{Signdate}} on the
    • Tip of the Week #69 – Automate your Zoho TeamInbox tasks with n8n integration.

      Don’t waste time repeating the same tasks—like sending follow-up emails or adding new contacts. Let automation save the day. With n8n, an open-source automation tool, you can connect your favorite apps and let them handle the busywork for you. You don’t
    • Multi Page/Step Forms in creator

      Greetings i was wondering if it's possible to create multipage/step forms on creator similar to what we have on zoho forms. is that possbile? Thanks
    • Package Geometry

      how can i add the dimensions and weight capacity of the available boxes to be default in the system everytime we use it ?
    • How to create a Master Kanban Board that syncs with Child Projects?

      Hello, We're currently using Zoho Sprints for managing our interdepartmental teams, and we're looking to enhance our workflow using Kanban boards as part of a company-wide productivity improvement initiative. Our goal is to implement a project structure
    • Writer.. Broken?

      Hello,  Writer has been really good to me during the months I've used it, up until now.  I usually launch the app by tapping the icon and I could immediately pick up where I left off.  Now I'm greeted by a loading circle not reaching 100% and I only have the option to create a new account.  By pressing that button it now switches to a login screen and I can access my account. However, it seems (only speculating ofc) to be stuck in cell-phone mode? everything looks scrambled.  I can't access any of
    • How to access Recruit Variables in a Deluge function?

      I have set up Recruit Variables in Zoho Recruit, and I would like to know how to retrieve these variables from within a Recruit custom function (Deluge). Could someone please explain the correct way to access them? I tried the following code, but it did
    • Upon De activate a user what name doe sthe contacts candidates go under?

      When deactivating a user, does the user name remain the same, as the candidate owner? If not what/who, does it change to? Do I need to change the user name in contacts and candidates before I deactivate the user?
    • Weekly Tips: Customize alerts from your Priority Users

      You might receive hundreds of emails daily, but messages from your manager, clients, or team leads often require immediate attention, as they may contain urgent requests or critical updates. How would you ensure you never miss important messages from
    • Maximum 100 records in Sheet View is limiting. How can I increase this?

      Thanks in advance for any help with this. There was a similar post that showed answered but it did not help with increasing the number of records you see in a Sheet View. Editing in the Sheet View is fast and efficient but I have 3500 records and I need
    • Revenue Management: #3 Revenue Recognition Simplified

      In continuation of the previous post on how to compute revenue recognition, let's explore a solution that helps businesses handle real-world complexities. While the Accounting Standards provide a clear framework for recognizing revenue, the real challenge
    • Tip #40- Strengthen Remote Support with IP-based Restrictions in Zoho Assist– ‘Insider Insights’

      Protecting sensitive data and preventing unauthorized access is a top priority for any organization. With IP-based restrictions in Zoho Assist, you can ensure that only users from trusted networks can initiate remote support sessions. Say your IT team
    • Push Invoices to Xero Manually

      Hi guys, I'm wondering if anyone has wanted to do this and has a workaround or knows of an app that may be able to help with this. I sell B2B and B2C. The customers can purchase on our website or through marketplace, all of which send sales to zoho. The
    • OpenAI error code: 1010 in a Zobot

      Please see short linked screen recording. Insights welcome. Please and thank you! https://workdrive.zohoexternal.com/external/f3247ba9c872639157b707700c0300c433c7664aea924a034f4da3c3ad2e355f
    • Ability to Create Sub-Modules in Zoho CRM

      We believe there needs to be a better, more native way to manage related records in Zoho CRM without creating clutter. Ideally, Zoho would support "sub-modules" that we can create and associate under a parent module. Our use case: We have a custom module
    • Installing EMAIL Setup in New Domain

      Respected Support team, I'm facing an issue with cloudflare in Pakistan, I want to setup Zoho Mail Setup but I Don't know how to enable Zoho mail setup without cloudflare. My Website https://stumbleguymod.com/ is using CF, and I want a different Zoho
    • Signature change

      I cannot see how to change signature or out of office details easily now in the new format.
    • Inventory API - Retrieve all uploaded product / item images

      I know that I can get the primary image for each product / item or composite item, by using the /image endpoint.  https://inventory.zoho.com/api/v1/compositeitems/<item-id>/image?authtoken=<TOKEN> This will return only one photo, even if the item has multiple images uploaded. Is there a way to retrieve all images stored for an item via the Zoho Inventory API?
    • Ebay Integration malfunction

      My eBay integration in Inventory has always worked well. It suddenly malfunctioned. It is creating its own parts in Inventory that are unavailable instead of selling the parts I've always sold. Tech help was unable to resolve this. The latest sale attempt
    • Introducing Bin Locations In Zoho Inventory

      Hello users, We are excited to let you know that your wait for the Bin Locations feature has now come to an end! Yes, you heard us right! We are here to introduce the much-awaited Bin Locations now in Zoho Inventory. But before we dive into the feature
    • how to get all the records in the custom View more than 200 records , Without using the page Concept

      how to get all the records in the custom View more than 200 records , Without giveing page as default in the Loop Concept Pls help how We can Achive this void schedule.Lead_Attempt_To_contact_schedule_10_30() { pages = {1,2}; for each pg in pages { query_map
    • The way that Users can view the ticket

      I have created users. What I would like to achieve is the following: All users under the same company account should be able to view each other’s tickets.
    • Zoho UAE SMS/WHATSAPP

      Hello everyone, so I have a question as regards DC and their impact on automation, integration and app usage. For example I am working with a UAE clientniw but each time I tried to connect their WhatsApp and sms then automate their process I tend to receive
    • Looking to Flag or Tag contacts/ accounts on Zoho Desk?

      I am looking for a way to flag certain accounts and make it obvious on the views pages. So for example if a has a certain package or needs extra attention it is clear before even clicking on the ticket. This could be via adding a tag or flag onto an account,
    • Next Page