## Zoho Billing - Product, solutions, integrations, support, and resources Index Access the complete documentation index at: https://www.zoho.com/kw/billing/llms.txt Use this file to discover all available documentation pages before proceeding. # SDK Implementation Follow these best practices when implementing the In-App Purchase SDK to ensure consistent behaviour, accurate data synchronisation, and reliable subscription management across your iOS and Android apps. * * * ## Set Up Your Zoho Billing Organization Configure the following settings in your Zoho Billing organisation before you begin SDK integration. ### Enable Pause and Resume The App Store and Google Play Store send subscription pause and resume events to Zoho Billing as part of the subscription lifecycle. For Zoho Billing to process these events and keep the subscription record in sync, enable the **Pause and Resume** setting in your organisation. To enable this in Zoho Billing: * Log in to your Zoho Billing organisation. * Go to **Settings** in the top corner. * Navigate to **General** under _Subscriptions_. * Toggle the **Pause and Resume** to enable. If this setting is not enabled, pause and resume events received from the store cannot be applied to the subscription in Zoho Billing. ### Prevent Duplicate Customer Display Names The SDK passes a `displayName` to Zoho Billing via `setUserDetails()`. When no matching customer is found by `userId` or email, Zoho Billing attempts to create a new customer using this display name. If a customer with the same display name already exists and the duplicate-name setting is enabled in Zoho Billing, the sync can fail. To disable duplicate customer display names in Zoho Billing: * Log in to your Zoho Billing organisation. * Go to **Settings**. * Navigate to **Customers** under _Module Settings_. * Uncheck the **Allow duplicates for customer display name** field. If duplicate customer display names are allowed, Zoho Billing may create multiple customer records for the same display name and the subscription sync may fail. ### Display Store Prices Always display the localized price returned by the store, not the price stored in Zoho Billing. Zoho Billing stores a plan’s price in your organisation’s base currency only and cannot reflect what a user in a different region is actually charged. The store returns the applicable localized price for each currency and region. * For iOS, use `skProduct.displayPrice` from the plan’s `skProduct` object. * For Android, use the price returned in the `productDetails` object in the `ZSPlan` object. ### Configure Plans in Each Channel Set up plans for each store before mapping products in SDK code. See [iOS plan setup](/kw/billing/help/omnichannel-subscription/ios/set-up-plans.html) and [Android plan setup](/kw/billing/help/omnichannel-subscription/android/set-up-plans.html). * * * ## Integrate Each Channel Integrate your app with each store channel before testing subscriptions end to end. See [iOS App Store integration](/kw/billing/help/omnichannel-subscription/ios/app-store-integration.html) and [Android Play Store integration](/kw/billing/help/omnichannel-subscription/android/play-store-integration.html). * * * ## Identify Customers Consistently If your customers can subscribe through both your website and mobile app, use the same customer reference across both channels. * For web purchases, pass `channel_customer_id` when creating customers or hosted-page subscriptions. * For mobile in-app purchases, pass the same value as `userID` when initializing the SDK. When the same email address or customer reference is used, Zoho Billing links the in-app purchase to the existing customer record instead of creating a new one. ### Match Customers Imported via Web If you import customers into Zoho Billing using a CSV web import, include the `channel_customer_id` field in your import file. Set this to the same value you pass as `userId` in `setUserDetails()` when initializing the SDK. Zoho Billing uses this field to match the in-app purchase to the existing customer record instead of creating a new one. * * * ## Initialize the SDK Configure these SDK values to prevent synchronization issues. ### Map Subscriptions to the Right Product Each subscription product in Zoho Billing has a unique identifier (`zsProductId`). Pass this value when initializing the SDK so in-app purchases are mapped to the corresponding subscription item in Zoho Billing. The **Plan Code** in Zoho Billing must match the corresponding **Product ID** in App Store Connect or Google Play Console for sync to work. You can retrieve `zsProductId` from the subscription URL in Zoho Billing or by using the Products API. ### Configure the Data Centre The SDK communicates with the Zoho Billing organisation based on the data centre domain you configure. If you manage multiple organisations, specify the domain for the organisation you want to sync with. **Note:** Using the wrong domain routes requests to a different data centre, causing synchronisation failures. ### Use the API Keys Use separate API keys for your test and production environments. Load the appropriate credentials based on your application’s environment to ensure test purchases and production purchases are synchronized with the intended Zoho Billing organisation. * * * ## Manage the SDK Lifecycle Initialize, update, and release the SDK properly throughout your application’s lifecycle to ensure consistent subscription management. Follow these steps: * Initialize the SDK when your application starts, even if the customer has not signed in. You can initialize the SDK with an empty `userID` and update it after authentication. * Reinitialize the SDK after the customer signs in with the authenticated user’s identifier. This ensures future purchases are associated with the intended customer in Zoho Billing. * Call `finish()` when the SDK instance is no longer required. This releases SDK resources and prevents unnecessary background activity. * Disable SDK debug logging before going live. Enable debug logging only during development and troubleshooting. For channel-specific implementation details, see [iOS SDK implementation](/kw/billing/help/omnichannel-subscription/ios/ios-sdk-implementation.html) and [Android SDK implementation](/kw/billing/help/omnichannel-subscription/android/android-sdk-implementation.html). * * * ## Receive Subscription Events Configure the Channel Notification URL so Zoho Billing can receive real-time subscription event notifications from the App Store or Google Play Store. Once configured, Zoho Billing automatically processes subscription events such as renewals, cancellations, refunds, billing retries, and subscription status changes. See the [iOS](/kw/billing/help/omnichannel-subscription/ios/configure-notifications.html) and [Android](/kw/billing/help/omnichannel-subscription/android/configure-webhook.html) setup guides for step-by-step instructions. * * * ## Validate Entitlements on Your Server Use your server as the source of truth for subscription status. Although the SDK provides subscription information, always verify the customer’s subscription status through your backend before allowing access to paid features. ### Do Not Rely Only on SDK Responses The SDK returns the latest subscription information available on the device. Store notifications or network delays might temporarily affect this state. Verify the subscription through your backend before granting access to certain features. ### Retrieve Subscription Details from Your Server After a purchase is completed, send the subscription identifier to your backend. If the corresponding webhook has not yet been processed, retrieve the latest subscription details from Zoho Billing before granting access. This provides a reliable fallback when subscription events are delayed. ### Prevent Trial Abuse If your application offers free trials across multiple channels, implement server-side validation to prevent customers from claiming multiple trial periods. App Store and Google Play might enforce trial eligibility for purchases made through their platforms. However, if customers can subscribe through additional channels, implement your own validation logic to ensure each customer receives only the trial benefits they are eligible for. **Note:** If you need help setting this up, reach out to support at [](mailto:support@zohobilling.com)[support@zohobilling.com](mailto:support@zohobilling.com). * * * ## Handle SDK Errors The SDK returns error codes whenever an operation cannot be completed. Handle these errors in your application to improve reliability and troubleshooting. You can use the error codes to: * Log recurring issues for analysis. * Display clear, user-friendly error messages. * Implement retry or recovery logic where appropriate. * Notify your team when unexpected failures occur. Avoid displaying raw SDK error messages directly to end users.