Integration Guide

Overview

There are a few simple steps to start using Xendit Subsriptions. Based on different needs of our merchants, Xendit allows configurations to be made to tailor to specific needs. In this Subscriptions guide, we will first walk through the basic features of Subscriptions followed by how advanced features can be configured.

High level API flow for creation of Subscriptions plans

High level API flow for creation of Subscriptions cycles (each billing instance)

Preparations before creating a Subscriptions Plan

Before creating a Subscriptions plan on our Create Plan endpoint, there are 3 pieces of information that will require preparation - customer information, payment method information, and schedule of recurrence. Xendit uses the customer object, payment method object and schedule object to store these information correspondingly.

Creating a customer object

The first step to Subscriptions is to create a customer object via the Create Customer endpoint. The information in this object is crucial as it will be used in notifications to end users. It is recommended to provide all details accurately so that notifications will be sent smoothly.

Example for create customer request -

POST https://api.xendit.co/customers 
{
    "reference_id": "test_reference_id",
    "mobile_number": "+6218181818181",
    "email": "honeybadgey@xendit.co",
    "type" : "INDIVIDUAL",
    "individual_detail": {
        "given_names": "Honey Badgey"
        }
}

Do note that the customer object created is reusable across multiple plans, one customer_id can be used to create multiple Subscriptions plans.

For best compatibility, please use version 2020-10-31 for Create Customer endpoint.

Creating a payment method object (Optional)

This is an optional step as Xendit provides an account linking/ card binding UI (via Create Subscriptions Plan endpoint) to create a payment method object. If merchant opts to use the UI provided by Xendit, the payment method object will be notified to our merchant via the recurring.plan.activated webhook.

Using Xendit's UI has several advantages over building your own -

  • Payment channels will be maintained by Xendit as we add more channels with autodebit feature
  • Xendit handles the complex security requirements and audits for compliance with payment providers/ networks.

Merchants who opt to provide their own user flow will have to create a payment method object via the Create Payment Method endpoint.

  • Set up your callback URL via Xendit dashboard settings page - under payment method
  • Hit POST /v2/payment_methods endpoint in order to initialize the account linking process. Make sure that the following parameters are provided:
    • type - The type of the payment method you are trying to link
    • reusability - It should be set to MULTIPLE_USE so that it can be used for future payments or for Subscriptions payments
    • customer_id - Linking typically requires you to create a Customer Object so that the payment method can be attached to it
    • ewallet or direct_debit or card object - to place the channel-specific properties to initialize linking.

Example for create payment method request -

POST https://api.xendit.co/v2/payment_methods 
{
  "type": "EWALLET",
  "reusability": "MULTIPLE_USE",
  "ewallet": {
    "channel_code": "OVO",
    "channel_properties": {
      "success_return_url": "https://your-redirect-website.com/success",
      "failure_return_url": "https://your-redirect-website.com/failure"
    }
  },
  "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
  "metadata": {
    "sku": "ABCDEFGH"
  }
}
  • Once the API returns a successful response, the account linking process has started.
  • If the status of the response is "REQUIRES_ACTION", this means that an additional step is needed for the account linking to be successful. Most common actions required:
    • Redirecting the end user to a webpage for confirmation
    • Via a one-time code for authorization validated via an API
  • Expect a Payment Method Activated Webhook to be sent once the payment method has been successfully authorized for payments.

Creating a schedule object (Optional)

Creation of a schedule object on Create Schedule endpoint is optional. Merchants can either pass in the schedule object directly on every Create Subscriptions Plan endpoint request or create a schedule_id upfront before passing it into the Create Subscriptions Plan endpoint.

Depending on the merchant's use case, either approach could be more suitable. We recommend merchants to create the schedule object on Create Schedule endpoint only if they have a need to control or manage the subsriptions interval logic of multiple Subscriptions plans at once.

Either way, merchants should prepare this object for their use case. Some examples are given below -

Example (below) of a basic schedule configuration -

{
  "interval": "MONTH",
  "interval_count": 1,
  "total_recurrence": 12,
  "anchor_date": "2022-02-15T16:23:52Z"
}

Example (below) of a monthly subsriptions with retries (e.g. Video Streaming) -

  1. The provider usually charges once a month without a fixed end date
  2. There is also no specific date which the provider wants to charge the end user, which means the bill next month will be on the same date as when the plan was initially created
  3. The provider wants to retry the payment two more times in case the first attempt fails, each attempt should be 3 days apart
  4. To not annoy the end user, the merchant only wants to notify the end user on the second attempt
{ 
  "interval" : "MONTH", 
  "interval_count" : 1, 
  "retry_interval" : "DAY", 
  "retry_interval_count" : 3, 
  "total_retry" : 2, 
  "failed_attempt_notifications" : [2] 
} 

Example (below) with monthly subscriptions with fixed number of cycles and fixed date (e.g. School Tuition) -

  1. The provider usually charges once a month for a fixed 2 years course of education
  2. The provider wants to charge the end user every 25th of the month
  3. The provider wants to retry the payment two more times in case the first attempt fails, each attempt should be 3 days apart
  4. Because education is important for the end user the merchant wants to notify the end user on every failed attempt
{
  "interval" : "MONTH",
  "interval_count" : 1,
  "total_recurrence" : 24,
  "anchor_date" : "2020-11-25T16:23:52Z",
  "retry_interval" : "DAY",
  "retry_interval_count" : 3,
  "total_retry" : 2,
  "failed_attempt_notifications" : [1,2]
}

Creating a Subscriptions Plan

Creating a Subscriptions Plan Object

Once you have completed the preparation steps, you are now ready to use the Create Plan endpoint. With the information from the preparation steps, our merchants would have most of the information required to create a Subscriptions plan. During this step merchants would be able to configure a few more settings for their end users. These include -

  1. immediate_action_type parameter - whether the Subscriptions plan should initiate an immediate action. When this parameter is used, a special cycle with type "IMMEDIATE" will be created. Xendit will try to perform the action of payment during Plan Creation. If the immediate payment fails, the plan will be deactivated automatically. This parameter helps merchants proceed with the plan creation only if the end user manages to complete the immediate payment transaction.
  2. notification_config parameter - defines the type of notification that the end user should receive.
  3. failed_cycle_action parameter - whether the subsriptions plan deactivates when it encounters a failed cycle. This parameter helps merchants to handle the subsriptions plan in the event that a cycle has exhausted all the retries and failed. Merchants can use this parameter to either “STOP” the subsriptions plan automatically or “RESUME” to ignore the failure and continue on with the next payment cycle.

With all this information set up, the subsriptions plan is good to go and what’s left is to prepare an endpoint to listen to the webhooks for updates to your subsriptions plan.

POST https://api.xendit.co/recurring/plans 

Example creating subsriptions plan with schedule object without payment method object -

{
  "reference_id": "test_reference_id",
  "customer_id": "cust-uhdquwy18237y213",
  "recurring_action": "PAYMENT",
  "currency": "IDR",
  "amount": 100000,
  "schedule": {
    "reference_id": "test_reference_id",
    "interval": "MONTH",
    "interval_count": 1,
    "total_recurrence": 12,
    "anchor_date": "2020-02-15T16:23:52Z",
    "retry_interval": "DAY",
    "retry_interval_count": 5,
    "total_retry": 5,
    "failed_attempt_notifications": [2,4]
  },
  "immediate_action_type": "FULL_AMOUNT",
  "notification_config": {
    "recurring_created": ["WHATSAPP","EMAIL"],
    "recurring_succeeded": ["WHATSAPP","EMAIL"],
    "recurring_failed": ["WHATSAPP","EMAIL"]},
  "failed_cycle_action": "STOP", 
  "metadata": null,
  "description": "Video Game Subscription",
  "items": [
      {
          "type": "DIGITAL_PRODUCT",
          "name": "Cine Mraft",
          "net_unit_amount": 100000,
          "quantity": 1,
          "url": "https://www.xendit.co/",
          "category": "Gaming",
          "subcategory": "Open World"
      }
  ],
  "success_return_url": "https://www.xendit.co/successisthesumoffailures",
  "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
}

Example passing in the schedule_id and payment_method_id -

{
  "reference_id": "test_reference_id",
  "customer_id": "cust-uhdquwy18237y213",
  "recurring_action": "PAYMENT",
  "currency": "IDR",
  "amount": 100000,
  "payment_methods": [{
      "payment_method_id": "pm-asdaso213897821hdas",
      "rank": 1
    }],
  "schedule_id": "resc-uhdquwy18237y213",
  "immediate_action_type": "FULL_AMOUNT",
  "notification_config": {
    "recurring_created": ["WHATSAPP","SMS","EMAIL"],
    "recurring_succeeded": [],
    "recurring_failed": ["WHATSAPP","SMS"]},
  "failed_cycle_action": "STOP", 
  "metadata": null,
  "description": "Video Game Subscription",
  "items": [
      {
          "type": "DIGITAL_PRODUCT",
          "name": "Cine Mraft",
          "net_unit_amount": 100000,
          "quantity": 1,
          "url": "https://www.xendit.co/",
          "category": "Gaming",
          "subcategory": "Open World"
      }
  ],
}

In the subsections of this documentation, there will be specific example of how merchants can set up their Subscriptions based on their use case of either - fixed amount subscriptions or usage based subscriptions.

Handling Subscriptions Webhooks

It is important to know what webhooks are available and when they are triggered. This helps to plan your system’s response to each event. The table below lists and describes the types of webhooks available.

Webhook eventTriggerDescription
Subscriptions Plan Activation recurring.plan.activated1. When a Subscriptions plan has been successfully created 2. Or, when a Subscriptions plan with immediate_action_type has been created AND the corresponding immediate action was successfulMerchants can use this as an indication that the Subscriptions plan was successfully created and it will proceed for the defined schedule. If this is not received, the plan would not proceed
Subscriptions Plan Deactivation recurring.plan.inactivated1. When a Subscriptions plan with a defined total_recurrence value has finished the total number of cycles 2. When a Subscriptions plan with failed_cycle_action = "STOP" met with a "FAILED" Subscriptions cycle 3. Or, when a Subscriptions plan with immediate_action_type has been created AND the corresponding immediate action failedMerchants can use this notification to close off their Subscriptions plan with a particular end user, as a indicator to stop provision of goods/ service
Subscriptions Cycle Creation recurring.cycle.created1. When the plan is created, a cycle with "SCHEDULED" status will be created regardless of whether the plan has set any immediate_action_type value. 2. Or, when the upcoming cycle changes status from "SCHEDULED" to "PENDING" (the first payment action is being executed)Merchants will get the notification of the upcoming Subscriptions cycle being created. Merchants will be able to adjust certain values of the upcoming Subscriptions cycle using the update Subscriptions cycle endpoint
Subscriptions Cycle Successful Action recurring.cycle.succeededWhen one of the configured attempts and its action has succeededMerchants can use this notification as an indication that end user has successful paid for the specified interval
Subscriptions Cycle Retrying Action recurring.cycle.retryingWhen the current attempt did not manage to get any successful actions AND there are still retry attempts configured for this cycleMerchants can use this notification as an indication that end user failed to pay for the specified interval but Xendit will continue to retry for payments
Subscriptions Cycle Failed Action recurring.cycle.failedWhen all configured attempts (including the retry attempts) did not manage to yield any successful actionsMerchants can use this notification as an indication that end user failed to pay for the specified interval and no further actions will be taken

Common Failure Reasons for Subscriptions

API Errors

Refer to our Subscriptions APIs for common API errors

Payment Failures

Failure ScenarioFailure Reason
Customer's account has been restricted by eWallet providerACCOUNT_ACCESS_BLOCKED failure code via cycle failed callback
Customer's account detail is invalidINVALID_ACCOUNT_DETAILS failure code via cycle failed callback
Customer's account has reached maximum transaction limitMAXIMUM_LIMIT_REACHED failure code via cycle failed callback
Insufficient balance on customer's walletINSUFFICIENT_BALANCE failure code via cycle failed callback
Customer unlinked payment method out of our systemsINVALID_PAYMENT_METHOD_ID failure code via cycle failed callback

Last Updated on 2023-06-02