Zoho billing logo Help Docs
/

Android In-App Purchases SDK Implementation

The Android SDK (ZSInAppPurchaseKit) connects your Android app with Zoho Billing for plan sync and subscription lifecycle updates.

Pro Tip:

Before starting, review Best Practices for SDK Implementation.


Add the SDK to Your App

Add the SDK dependency in your app-level build.gradle file.

dependencies {
    implementation("com.zoho.subscriptions:inapp-billing:7.2.0")
}

Initialise the SDK

Initialise the SDK after user information is available.

For example:

// apiKey - The unique key generated for your organization in Zoho Billing.
// It is used for communication between the SDK and the Zoho Billing server.
// You can find it on the App Store integration page in Zoho Billing.

// zsProductID - The unique ID of the product created in Zoho Billing where your plans are configured.

// domain - The data center where your Zoho Billing organization is hosted.
// For example, if your organization is in zoho.com, use ZSDomain.COM.
val zsAPIConfiguration = ZSAPIConfiguration(
    apiKey = "YOUR_API_KEY",
    zsProductID = "YOUR_PRODUCT_ID",
    zsDCDomain = ZSDomain.COM
)

ZSAPIConfigurationCompanion.setAPIConfiguration(zsAPIConfiguration)

ZSInAppPurchaseKit.initialize(
    this,
    ZSAPIConfigurationCompanion.zsapiConfiguration
)

// userId - The unique ID of the user maintained in your server.
// For web subscriptions, this field corresponds to the channel_customer_id.

// userEmail - The user's email address.

// displayName - The user's display name.
ZSInAppPurchaseKit.getInstance().setUserDetails(
    userId = "APP_USER_ID",
    userEmail = "APP_USER_EMAIL",
    displayName = "APP_USER_DISPLAY_NAME"
)
Note:

For best practice guidance on the USER_ID, PRODUCT_ID, and DOMAIN parameters, see Match Customers Across Channels, Map Subscriptions to the Correct Product, and Configure the Correct Data Centre in the Best Practices guide.


Fetch Plans

Load available subscription plans. This retrieves only the plans configured in both Zoho Billing and Play Store (common plans) that are available for purchase.

    val arraylist = arrayListOf<ZSCustomFieldFilter>().apply {
       //If you have configured any custom fields in Zoho Billing, you can pass them here if needed. This is totally optional.
    }
   
   ZSInAppPurchaseKit.getInstance().getPlans(object : PlanDetailsListener
   {
        override fun onPlanDetailsFetched(zsPlans: ArrayList<ZSPlan>)
       {
           //Update the UI with the list of plans fetched from Zoho Billing and added in Google Play Console.
       }
   
       override fun onError(error: ZSError)
       {
           //Handle error logic
       }
   }, arraylist)

Initiate a Purchase

Initiate a purchase when a user selects a plan. This starts the Play Store purchase flow and syncs the subscription to Zoho Billing.

Before calling initiateNewPurchase, extend your activity with the PurchaseUpdationListener interface. When the user taps the purchase button in your UI, pass the corresponding zsPlan object to initiateNewPurchase.

   ZSInAppPurchaseKit.getInstance().initiateNewPurchase(
   activity = CURRENT_ACTIVITY_INSTANCE, 
   zsPlan = USER-SELECTED_ZSPLAN, 
   offerId = "", 
   purchasesUpdatedListener = CURRENT_ACTIVITY_INSTANCE, 
   zsCustomFields = customFields)
   
   override fun onStorePurchaseCompleted() 
   {
       //Purchase successfully done in Google Play Store, show a loading bar while the SDK syncs this purchase with Zoho Billing
   }
   override fun onPurchaseSyncedWithServer(zsSubscriptionDetail: ZSSubscriptionDetail)
    {
       //Purchase successfully synced with Zoho Billing. 
   }
   override fun onError(zsError: ZSError)
   {
       //Purchase failed. zsError.message will give the error message. Handle cases accordingly
   }
  

If the purchase is successful, the SDK syncs it with Zoho Billing and returns a ZSSubscriptionDetail object in the onPurchaseSyncedWithServer callback. Use this to verify the customer’s subscription status through your backend before allowing access to paid features. Zoho Billing also delivers the subscription details to your configured webhook. If the purchase fails, the error is returned in the onError callback.

To include custom fields in the subscription, pass them using the zsCustomFields parameter. If you are applying an offer, pass the offer ID as a custom field.

Offers

zsPlan.productDetails.subscriptionOfferDetails contains all the offers eligible for the current user and plan. Two types of offers are supported:

Introductory Offers

Introductory offers apply only to users who have not previously subscribed to the plan. Eligibility can be scoped to a specific plan or any plan, depending on your Play Console configuration. When introductory offers are configured, the SDK automatically selects the best eligible offer using this priority:

  1. Longest free trial - applied first, if available.
  2. Cheapest introductory price - applied if no free trial is available.
  3. No offer - applied if neither is available.
Note:

Google Play Store is the sole determinant of introductory offer eligibility. As a best practice, display a message in your UI stating that introductory offers are available only to eligible customers.

Developer Determined Offers

For developer determined offers, your app decides eligibility based on your business logic. When you want to apply one of these offers, pass the offerId to initiateNewPurchase. If no developer determined offer should be applied, pass an empty string.


Restore a Purchase

Add restore support for users who purchased in Play Store but failed sync due to temporary issues.

   ZSInAppPurchaseKit.getInstance().restorePurchase(restorePurchaseListener = object :RestorePurchaseListener
   {
       override fun onPurchaseRestored(zsSubscriptionDetail: ZSSubscriptionDetail)
       {
           //Purchase has been restored successfully and synced with Zoho Billing.    
       }
        override fun onError(error: ZSError)
        {
            //Purchase was not restored.           
       }
    }, storeOrderId = "")

Fetch Current Entitlements

Retrieve the user’s active subscriptions directly from Play Store. Use this to display current subscription status and entitlements in your app.

   ZSInAppPurchaseKit.getInstance().getPurchaseMetadataFromStore(object: PurchaseMetadataListener
         {
               override fun onPurchaseDetailsFetched(purchases: MutableList<Purchase>)
               {
                    //Append the purchase details to when user contacts support via mail if necessary
               }
               override fun onError(error: ZSError)
               {
                     //Purchase data could not be fetched.   
              }
    })

Clear User Info

Clear the SDK user data when a user logs out or your app terminates the session. This ensures user information is not retained.

   ZSAPIConfigurationCompanion.clearAPIConfiguration()
   ZSInAppPurchaseKit.getInstance().clearUserDetails()

Was this document helpful?
Yes
No

Thank you for your feedback!