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

    • how to upload a reviewed price list in zoho to replace the existing price list

      Price list upload for my zoho books
    • Company details and emails

      Our company has recently been rebranded and we have new email address - How do I update information for users. I have tried to re invite users with new email but it sends me to organization and there is no where I can change the email or invite with new
    • Linking Resale Certificates to Customer Locations

      Florida Resale Certificates must be on every customer invoice. We have customers with multiple locations and each location has a seperate FL Resale Certificate. The FL Resale Certificate makes the transaction EXEMPT from Sales Tax. Can FL Resale Certificate
    • Notebook App Not Opening

      I love this app but for the last 2 days it recuses to open. My phone tells me the app is bugged and I must wait for a new update. Is anyone else having this problem or is something going on with me? I have many important notes that I can't necessarily
    • Admin and Dispatcher Users show as Field Technicians in Dispatch Module?

      Hi Zoho, Our Admin and Dispatch user both show up as Fied Technicians / Field Agents in the Dispatch module, but they most certainly should not be assigned to any of the work orders and service appointments. These users are NOT service resources. How
    • Copy Sales Order Reference# to Purchase Order#

      Hello, We use our customer's purchase order number as the order number on our purchase order to the supplier.  We direct ship everything from our suppliers and the customers then see their PO number on the packing notes (instead of a sequentially-generated one). Therefore, is it possible to use automation to copy the Sales Order Reference# (customer PO) to the respective Purchase Order# (our PO) when converting the Sales Order to a Purchase Order?
    • Free webinar: Zoho Sign in Q2 2025: A quick walkthrough

      Hi there! We’re halfway through the year—and Zoho Sign has some exciting enhancements to show for it! Join us in our upcoming webinar to discover what's new and what you can look forward to. What will this session cover? Explore the newest features introduced
    • Using a Webhook as an Action

      I have been able to setup where I can use a webhook as a Trigger, but I am wondering how I can use a webhook as an Action. In the Zoho Flow Builder when using Zoho CRM as a trigger, I do not see a way to invoke a URL to POST json data that can be used
    • Adding commas to a numeric value

      Hi, I want to add commas to numeric values so that they look like money E.g 1234.56 to 1,234.56 12345.67 to 12,345.67 12345678.90 to 12,345,678.90 How do you do that in Deluge? Thanks for the help
    • Pushing Zoho People leave into Microsoft calendar: how to chose how "event" is shown (busy, free etc)

      Hi, how can I select how a "leave" event is pushed into Microsoft calendar? I want for leave "working elsewhere" to show as working elsewhere and NOT as busy.
    • Tiktok and Instagram Carousel with Music

      Is it possible to add music or sound (can be downloaded or uploaded or attached) when we upload carousels in IG and Tiktok?
    • [Product Update] Locations module migration in Zoho Books integration with Zoho Analytics

      Dear Customers, As Zoho Books are starting to support an advance version of the Branches/Warehouses module called the Locations module, users who choose to migrate to the Locations module in Zoho Books will also be migrated in Zoho Analytics-Zoho Books
    • Once again, non-admins can no longer revise the site map

      Not sure when this change happened, but it's a problem now. This appears to be a regression on this issue: https://help.zoho.com/portal/en/community/topic/bug-non-admins-can-no-longer-revise-the-site-map ... which was solved. That issue was also a regression.
    • Detail View in Mobile without Labels

      Zoho creator 6. I have been trying to acheieve this but not able to. I have a quick view of my articles using custom layout for mobile. When i tap on an article it opens in detail view on my mobile which has two cols. Left displays label and right the
    • Updating task using excel file

      Hi, Is there a way to update existing tasks using excel file import?  Thanks
    • Cross module filtering is now supported in CRM

      Editions: All DCs: All Release plan: This enhancement is being released in phases. It is now available in AU, JP, and CN DCs. Help resource: Advanced filters The Cross-module filtering enhancement is now available to all CRM accounts in the following
    • Before Going To The Qc stage , site ready ness file upload mandtoty how to achive this in the blue print transition

      Before Going To The Qc stage , site ready ness file upload mandtoty how to achive this in the blue print transition On click of the Predelivery transition can we show site ready ness file upload mandtoty or on click of the QC show the alert message site
    • Note cards are duplicating

      Hi, I've been using this app for some time and love it. Recently I've noticed that upon closing a note card, it creates a duplicate. If I exit the notebook it's in and go back, everything is back to normal. Not a major issue but still a little annoying.
    • Where is the (Bulk) Notes Export function from Notebook ???????

      I have seen various threads over the last two years on this and basically no action from ZOHO at all ! BTW having to go to an individual note and export to PDF (which now doesn't even work ) or some sort of zoho format is by no means the answer ! I still can't see any sort of bulk (or even individual) export function across notes. This is really poor for a notes product that is nearly 4 years old from a "major vendor".  I now have a large number of notes (some with images) that I want to export and
    • Again about the backlighting of the search query when searching in a client for Linux

      Some time passed, I installed a client for Linux version 3.4.0, but I still did not receive the promised search with the backlighting of the search query how it was implemented in the client for android. In the previous topic, you told me that this function
    • Important! ZipRecruiter Sponsored Posting Plan Changes in Zoho Recruit

      Greetings, We’re reaching out to inform you about an important upcoming change to the ZipRecruiter Sponsored job board integration within Zoho Recruit. What’s Changing? Starting June 1, 2025, Zoho Recruit will be updated with ZipRecruiter's latest pricing
    • In the Blue Print Transition requirement received it will show 8 check field in pop up if they any one of this field then only move to next stage Ist quote

      In the Blue Print Transition requirement received it will show 8 check field in pop up if they any one of this field then only move to next stage Ist quote Pls help how i fix this
    • Linking Multi-UOM Barcodes to Products in Zoho Books

      Greetings, I'm using Zoho Books for retail shop and I'm running into a bit of a challenge with products that have multiple Units of Measurement (UOMs) and corresponding barcodes. For example, I sell cigarettes both as individual packets and in cartons
    • Convert Item to composite item

      When using Zoho CRM integrated with Zoho Inventory/Books, the item creation process is a little messy. After a few years of trial and error, we have settled on creating items in CRM, which are sync'ed to Zoho Inventory using Zoho's own internal integration.
    • Mapping “Account Name” from CRM to Campaigns

      I’m syncing our Contacts list to Campaigns and want to select “Account Name” as an available field. Account Name does not appear in the drop down menu for CRM field even though Account Name is a field in our standard layout. How can I make it availa
    • Zoho Campaigns to Zoho Analytics Sync Fails – Field Mapping Shows But Not Applied

      I’m facing a persistent issue with the Zoho Campaigns integration to Zoho Analytics in my workspace. Here’s a detailed description of the problem: Under Edit Setup, I see a field mapping summary that shows: DataField Mapping: Most Recent Login However,
    • Host in US Data Centre

      I humble apply to be registered on US Data centre
    • Multiple images, one record

      I have a form that is used to capture the following info: -Facility Name -Origin -Shipment # -Picture of Damaged Pallet (Image field) I want to be able to capture multiple pictures without having to create a new record, as there might be multiple damaged pallets on the shipment. Obviously, one never knows how many damaged pallets might be on a shipment so I'd prefer not to create 20 image fields and have most of them unused.  I'd prefer that they have an option to add another image only if they need
    • how to dynamically upload multiple images for single record?

      Is the use of dynamic multiple images in a single record supported? I've searched but have not found the answer. If it is supported, how is it done? I saw 1 suggestion to add a sub-form but that doesn't seem to be the answer. I don't want to add a set number of image fields. Each record would have a different number of images. I want the addition of images to be dynamic. thanks
    • Multi-upload field

      Hi I need to include a file upload field that allows the user to select multiple files and upload all at once. I hope I can do this with HTML, I'm new to merging HTML and deluge... Can I trigger a hidden file upload window to appear On User Input of a field in an embedded form? Thanks! Levi
    • is it possible to add multiple attachments to a record?

      Hello, I'm trying to add functionality so that a record can have several associated attachments. I obviously added a File Upload field to my form, but that appears to only allow one total. Is there a way around this? Thanks, - Kevin
    • multiple upload files in zoho form

      Hi,  I need upload multiple files  in a single upload field thkns
    • Keeping Track of Email Threads

      Hi, Z CRM is great for tracking all the activities one would want to track whilst qualifying leads, converting to customers, closing deals etc etc, however.... ....although I can use Z CRM to send an email to a lead/contact and have that recorded as an activity for other team members to see, there is no way of capturing an inbound email from that lead. Assume my lead replies to my email sent from ZCRM, in my case, the response arrives in my ZMail account. However I can't get it back into ZCRM to
    • Zoho Creator invokeUrl to retreive PDF

      I'm trying to retreive a record PDF to send to Print Node. Tried with and without the zoho_creator_connection. pdf_content = invokeurl [ url :"https://creatorapp.zoho.com.au/<org_namespace>/<app_link_name>/record-pdf/<report_link_name>/" + input.ID type
    • Bulk upload image option in Zoho Commerce

      I dont know if I am not looking into it properly but is there no option to bulk upload images along with the products? Like after you upload the products, I will have to upload images one by one again? Can someone help me out here? And what should I enter
    • Zoho App Builder

      I’m looking for a Zoho Creator developer to build a simple app for tracking site expenses for a construction company. Key features: mobile form, dropdowns for projects and expense types, photo attachment for invoices, auto-calculated totals, and Excel
    • Captcha can't be enabled conditionally

      Hi Problem: captcha on a form can't be enabled conditionally. Why is this a problem: Because I use the same form on our website (public) in the portal and mobile app. In the portal it works but in the mobile app it doesn't. So there should be a way to
    • ACH Returns Don’t Trigger Dunning or Reverse Payment in Zoho Subscriptions

      Zoho Billing marked an ACH payment as successful and kept the subscription active — even though the payment was later returned by the bank (NSF). There was no update to the invoice or subscription status, and I had to manually clean it all up. For credit
    • Zoho Sheet - Split cell diagonally fill half color

      is it possible to split a cell diagonally, fill different text in each half and ideally color them differently as well?
    • Calling Token API in Postman returning "error: invalid_client"

      Hello, I've been working on setting up an API to get data from zoho crm into a third-party application. I'm currently testing the setup in Postman, but I'm getting an error from the API to retrieve the access token. It keeps returning "error: invalid_client".
    • Next Page