1. Developer Docs
  2. Products
  3. Plans
    1. Plan Modifications
  4. Subscriptions
    1. Lifecycle
    2. How does XPay collect recurring payments?
    3. How do I create a subscription now and later start the billing cycle?
    4. Payment methods
    5. Skip and unskip
    6. Pause
    7. Resume
    8. Cancel
    9. Update a Subscription’s Schedule / Payment
      1. Modifying individual invoice
    10. Failure use-cases
      1. Retries
      2. Subscription Status
      3. How do I collect a failed recurring payment?
        1. Payment Link
        2. In-app experience
  5. Invoices
  6. Webhooks

E2E Integration Example

API Docs

Developer Docs

A subscription comprises three parts:

  1. Products
  2. Plans
  3. Subscription

Products

  1. A product needs to be created, against which a plan will be created and later subscribed.
  2. To start with, you will need to add these two required fields
    1. product name
    2. price
      1. The price of the products will be summed to calculate the total amount of a plan and used to create subscriptions against that plan.
      2. The pricing can be changed at the plan level and is discussed in detail here.
  3. The id field referring to SKU is an optional field, but if provided, it will be considered unique for a merchant and can't be added to another product object.
  4. The products will be shown in the invoice sent to the customer via XPay.

Product Price Update

  1. In the case of updating product prices, the plans and subscriptions associated with the products won't be updated automatically.

    1. The Update Subscription API will need to be called to update the price of each product for a subscription.
    {
    	"payment": {
    		"latest_product_price": true
    	},
    	"product": [
        {
            "name": "Ali",
            "product_id": "xpay_product_90e8c92b774641adad16325722fe8c20",
            "quantity": 1
        },
        {
            "name": " Raza",
            "product_id": "xpay_product_e302a0a0ec984e18aadd09e296323c8c",
            "quantity": 1
        }
      ],
    }
    

Plans

A plan is a schedule defining how merchants intend to collect recurring payments.

  1. In plans, the merchant will specify interval, every, etc.
  2. When a user selects a plan and pays, a subscription is created against that plan.
  3. A subscription is always created against a plan, and later recurring payments are collected as per that plan.
  4. The Plans API supports adding single or multiple products to one plan.

Interval

Interval
day
week
month
year

Update the plan

  1. If the plan updates, the existing subscriptions won’t be updated by default.
  2. To update subscriptions, the merchant needs to use the Update Subscription API with Plan ID to update individual subscriptions.
{
	"plan_id": "xpay_plan_6f51cae83bbb45bd8588fe0c95e4c2b6"
}

If plan_id is added, it will update the latest billing cycle, products, and payment from the plan ID and override any such value being added in the payload.

<aside> 💡 To update a subscription's pricing, billing cycle, etc., kindly refer to Update a Subscription’s Schedule / Payment.

</aside>

Plan pricing

By default, the price of each product will add up to the plan price. However, XPay supports manually adding amounts and currencies if pricing needs to be changed based on frequency, etc. In this case, the Create Plan API expects the amount: number and currency: string to be passed.

Subscriptions

  1. A subscription will be created against a plan, and the billing cycle will start from the start date.
  2. The start_date, plan_id, timezone, and payment_token need to be mentioned.

<aside> ⚠️ The subscription is not created at the customer level but at the plan level. If different plans are offered to different customers, then merchants will save those plans in their system.

</aside>

Lifecycle

Status Reason
inactive Payment Failed
paid Payment successful
draft Created but no action performed

How does XPay collect recurring payments?

For every recurring payment, XPay will create an invoice.

  1. This invoice will have an ID, an associate payment intent ID, a payment date, etc.
  2. The latest invoice status will be the subscription status at any given time.
    1. The subscription status will be inactive if the first two invoices are paid but the third one fails.
  3. The payment against the invoice will be attempted as per the start_date and plan provided.

How do I create a subscription now and later start the billing cycle?

This is the use case where

  1. A free trial is being offered.
  2. The user wants to checkout now and start a subscription at a later date.
  3. or any other case requiring authentication and authorization from the cardholder without starting a subscription.

The merchant can do this if the Payment Method token doesn’t exist.

  1. Create a PI of the minimum amount allowed by the acquirer.
  2. confirmPayment() SDK to authenticate, authorize, and collect payment method tokens.
  3. Use that PM in the Create Subscription API and collect_advance: false to be set. XPay will create a subscription and start collecting recurring payments as per the schedule.

Payment methods

  1. The payment method token needs to be provided before creating a subscription.

  2. After a successful payment, the payment method token will be provided in the SDK response and webhook.

  3. If the merchant already has a payment method, it can be provided while creating a subscription.

    1. If the subscription start_date is an upcoming date, the subscription will be attempted on that date, and the status will be changed from the draft.
  4. If the payment method token doesn't exist, then there are two approaches:

    Create a Subscription with PI

    1. The merchant will follow the same steps as normal payment but modify the Create Payment Intent API payload, add reason: “token” in the metadata and subscription object in the payload to specify subscription payment, and be provided with a payment method token.

      1. The XPay API will return a payment response and notify the merchant via the subscription_create webhook.
      2. The amount and currency can't be added here, but those from the plan will be used.
      // Create PI API Payload
      {
          "payment_method_types": "card",
          "customer": {
              "name": "",
              "email": "",
              "phone": ""
          },
          "shipping": {
              "address1": "",
              "city": "",
              "country": "",
              "zip": "",
              "shipping_method": ""
          },
          "metadata": {
              "order_reference": "",
              "reason": "token"
          },
          "subscription": {
              "plan_id": "xpay_plan_d081b7f5e8e74c37938597ee7e8cf444",
              "start_date": "2024-06-30T10:55:00Z",
              "timezone": "Asia/Karachi"
              //rest of the subscription payload which you want to add
          }
      }
      

    Create a token with PI and later call the subscription API

    1. The merchant will pass the reason: "token” in the Create PI API with a regular payload, and the payment method token will be provided in the SDK response and payment webhook.
      1. The merchant will follow similar steps, add a payment method token in the Create Subscription API, and add this key value in payload collect_advance: false. Here, XPay will not make a payment attempt to create a subscription.

<aside> 💡 The default configuration is collect_advance: false.

</aside>

What happens when a payment fails with collect_advance: true on creating a new subscription?

  1. When collect_advance: true is added to the Create Subscription API, a couple of use cases need to be handled.
    1. If the payment is successful, then a subscription will be created, the first invoice will be marked as paid, and the subscription status will be active.
    2. If the payment fails, then failure_action will be handled accordingly.

<aside> 🚧 Create Subscription API is not idempotent at the moment ****and if you have set ****failure_action: "CONTINUE" and attempt it twice, it will create two subscriptions.

</aside>

Skip and unskip

  1. The subscription invoice for a specific interval can be skipped, and no amount will be charged for that invoice.
  2. Only scheduled invoices can be skipped.
  3. The subscription can be unskipped before the invoice's payment date.

Pause

  1. The subscription can be paused, and no further payments will be attempted.
  2. By default, the pause is not allowed on an inactive subscription. However, the merchant can specify in the config to allow and override the default behavior.
  3. No new invoice will be created by default.

Resume

  1. The subscription can be resumed after it has been paused.
  2. The new billing cycle will start from the date it is resumed or any start_date specified.
  3. The payment attempt will be made, and on a successful attempt, the subscription will be resumed with active status.
  4. If a subscription is being resumed, when it has an earlier inactive status, the merchant will need to manually charge the unpaid invoice(s) via the Pay Invoice API.

Cancel

  1. The subscription can be canceled, and no new invoice or payment will be charged against it.
  2. Its status will be cancelled.
  3. Once a subscription is canceled, it can't be undone.
  4. By default, cancellation is not allowed on an inactive subscription. However, the merchant can specify in the config to override the default behavior.