Subscriptions
Introduction
UNIPaaS offers a flexible and user-friendly Subscription Solution designed to help businesses manage recurring payments effortlessly. Whether you’re running a SaaS platform or offering memberships, our subscription tools make it simple to handle recurring revenue while ensuring a seamless experience for your users.
Our Subscription Solution also enable your users' businesses that offer ongoing services to easily collect recurring payments, helping to generate revenue and ensure reliable cash flow management.
Subscriptions represent a set of ongoing payments linked to a single plan and payer.
Benefits
The UNIPaaS Subscription Solution offers a variety of benefits for platforms looking to integrate subscription management. These include:
Simplified integration: Easy-to-use APIs and embedded components allow you to set up subscription workflows quickly, freeing up resources to focus on growing your platform.
Flexible subscription management: Support for a wide range of subscription scenarios, including custom billing cycles, multiple payment methods, and dynamic pricing, ensures adaptability to your business needs.
Enhanced user experience: Provide your users with an intuitive way to manage subscriptions—set up, modify, or cancel plans directly within your platform’s UI.
Seamless branding: Fully customizable to match your platform's look and feel, the Subscription Solution creates a consistent and branded experience for your users.
Reliable performance: Handle recurring payments with precision, ensuring accurate invoicing and smooth processing, even as your customer base grows.
Security and Compliance: Built to meet industry standards for security and compliance, the Subscription Solution protects sensitive payment data and ensures regulatory peace of mind.
How subscriptions work
Plans and Subscriptions are the main objects needed to set up a successful recurring payments agreement between a buyer and a vendor.
The Plans object defines a single plan, including its price, billing cycle, and charge amount. While the Plans object is active, buyers can subscribe to that plan, creating a Subscriptions object.
The Subscriptions object represents a specific buyer subscription to a specific plan. It holds the subscription start and end dates, as well as information about the plan. The subscriptions object is linked to both a Plan and a buyer. Pausing a subscription will stop the billing cycle from running.
Subscription features
The following is a list of supported subscription features:
Feature | Available options |
---|---|
Payment methods | Credit cards and Direct Debit |
Fixed billing cycles | Daily, Weekly, Monthly, Annually |
Flexible charge date | |
Auto renewal | |
Free trial period | |
Setup fee | Configurable amount |
Retry logic | |
Web-hook notifications | List available below |
Flexible charge date
Coming soon
Auto Renewal
Subscriptions set to renew automatically will do so every time the expiration date is reached. When a subscription renews, a new subscription object is created with the same configuration. All renewed instances of the same subscription will have the same identifier
UUID that can be used to track the subscription history.
Setup Fee
Setup fees can be added as an additional cost billed with the first subscription occurrence in a single transaction. The setup fee is defined on the plan level and can only be billed in the same currency as the plan.
Free Trial
Free trial periods allow a subscription to be active for a certain period of time after its creation date without billing the buyer for that period. Trial periods are defined on the plan level, with the period defined by a combination of cycle length (i.e., day, week, month, year) and the number of cycles.
The Plan object
Each Plans object represents one plan with specific attributes. A plans object can have one of the 3 following statuses:
- Active - Users/customers are free to subscribe to this plan.
- Paused - New users/customers cannot subscribe to this plan. Those who already subscribed to this plan are not affected.
- Archived - This status is available only when there are no active subscriptions with this plan. Users/customers cannot subscribe to archived plans.
Main plan fields:
Name | Type | Description |
---|---|---|
name | String | Plan name |
description | String | Plan description |
price | Decimal | Plan price amount |
currency | String | Currency standard ISO 4217 |
periodUOM | Enum string | Defines the billing cycle type (days, weeks, months, years) |
period | Integer | The length of the plan in 'PeriodUOM' units |
trialUOM (Optional) | Enum string | Defines trial period cycle type (days, weeks, months, years) |
trial Period (Optional) | Integer | The length of the trial period in 'PeriodUOM' units |
status | Enum string | Defines the status of the plan |
autoRenewal | Boolean | Defines auto-renewal |
The Subscription object
Each Subscriptions object represents a single buyer subscription to a specific plan. A Subscriptions object is created once a buyer is either billed or starts a free trial period. Upon creation, Subscriptions objects inherit attributes from their relevant plan and can have one of the following statuses:
- Trial - The subscription is still in the trial period, and once the trial period ends it will either become Enabled or Canceled.
- Enabled - The subscription is active and ongoing, with billing based on the plan and cycle.
- On hold - Active subscriptions that are stopped temporarily. Status management made by platform, when subscription is on hold - we are just stopping create charges/authorizations until it goes to "enabled" again.
- Canceled - Inactive subscriptions that will no longer renew. “endsOn": the end of current period, next scheduled payments will be removed.
- Completed - Subscription has reached its expiration date and is now inactive.
Main subscription fields:
Name | Type | Description |
---|---|---|
planID | Int | The ID of the Plan object this subscription is linked to |
customerID | UUID | The ID of the buyer this subscription is linked to |
identifier | UUID | Used for grouping renewed subscriptions |
status | Enum string | Current subscription status |
paymentMethod | Object | Represents the payment method used to pay for this subscription |
price | Decimal | Subscription price. Inherited from plan |
currency | String | Currency standard ISO 4217. Inherited from plan |
periodUOM | Enum string | Defines the billing cycle type (days, weeks, months, years). Inherited from plan |
period | Integer | The length of the plan in 'PeriodUOM' units. Inherited from plan |
trialUOM (Optional) | Enum string | Defines trial period cycle type (days, weeks, months, years). Inherited from plan |
trialPeriod (Optional) | Integer | The length of the trial period in 'PeriodUOM' units |
setupFee (Optional) | Decimal | Fee amount that is charged upon subscription creation. Inherited from plan |
autoRenewal | Boolean | Defines auto-renewal |
nextBillingOn | Timestamp | Calculated field, holds the next (in cycle) billing date |
endsOn | timestamp | Calculated field, holds the subscription expiration date. |
isInBillingRetry | Boolean | Initiated once a payment fails. Means that retry logic is active for this subscription. |
nextBillingRetryOn | Timestamp | Next billing retry date |
Smart retry logic
UNIPaaS's Smart Retry Logic ensures seamless payment recovery and streamlined subscription management. By optimizing retry attempts and managing failed payments effectively, it minimizes involuntary churn and enhances the overall customer experience.
Key features
Three retry attempts per billing cycle
UNIPaaS automatically retries failed payments up to three times within the current billing cycle. Retry intervals are strategically timed to maximize payment success rates.
Cumulative billing on the next cycle
If payment recovery is unsuccessful within the current cycle, the outstanding amount is added to the next billing cycle’s invoice. This approach consolidates billing and provides an additional opportunity for recovery.
Auto-pause for unrecovered payments
Subscriptions are automatically paused if payments for two consecutive billing cycles fail, regardless of the number of retries attempted. This ensures that no further charges are made until the outstanding balance is resolved.
How smart retry logic works
- Initial payment failure: If a payment fails, UNIPaaS begins the retry process.
- Three retry attempts:
- Up to three smart retries are scheduled during the current billing cycle.
- Cumulative billing:
- Any unpaid amount from the current cycle is added to the next billing cycle’s invoice.
- Subscription pausing:
- If payments fail across two consecutive billing cycles, the subscription is marked as Paused to prevent further charges.
Example of a full retry flow
Scenario: A subscriber has a 10 GBP monthly subscription, and their payment fails on January 1st.
The retry and recovery process unfolds as follows:
Billing Attempt | Attempt type | Billing date | Billing amount | Transaction status | Subscription status |
---|---|---|---|---|---|
1 | Regular billing cycle | Jan 1st | 10 GBP | Failed (Soft) | Active |
2 | Retry #1 | Jan 2nd | 10 GBP | Failed (Soft) | Active |
3 | Retry #2 | Jan 9th | 10 GBP | Failed (Soft) | Active |
4 | Next billing cycle | Feb 1st | 10GBP + 10GBP | Failed (Soft) | *Paused |
Implementation
The key difference in implementing the Subscription solution for your platform (where your platform owns and collects the subscription fees) versus for your users (where your user/vendor owns the subscriptions) lies in the initial step: plan creation.
During plan creation, you determine who the plan owner will be. Once the plan is created, the subsequent steps remain the same for both scenarios.
Platform-owned plan
This section describes the scenarios for plan creation, which can be done in two ways: either using our API or manually through the user-friendly interface in the Platform Portal.
API
Make a POST/pay-ins/plans request to create a new plan:
Example of a request payload
{
"name": "string",
"description": "string",
"group": "string",
"price": 100,
"country": "GB",
"currency": "GBP",
"period": 12,
"periodUOM": "months",
"autoRenewal": false,
"vendorId": "string",
"trialUOM": "string", // (Optional)
"trialPeriod": 0 // (Optional)
}
To create a plan for your platform, provide vendorId field with your merchant ID (platform ID) value. You can find this ID in your Platform Portal.
Response
{
"id": "string",
"merchantId": "string",
"vendorId": "string",
"name": "string",
"description": "string",
"price": 100,
"currency": "GBP",
"period": 12,
"periodUOM": "months",
"trialPeriod": 0,
"autoRenewal": false,
"createdBy": "string",
"updatedBy": "string"
}
Platform portal
To create a plan using the Platform Portal, click the "Create a Plan" button in the Plans section and manually fill in the plan details. In the "Owner" section at the bottom, ensure the toggle remains off.
Vendor-owned plan
Make a POST/pay-ins/plans request to create a new plan:
Example of a request payload
{
"name": "string",
"description": "string",
"group": "string",
"price": 100,
"currency": "GBP",
"period": 12,
"periodUOM": "months",
"autoRenewal": false,
"vendorId": "string" //Vendor ID in a Complete onboarding status should be passed
}
Response in this case will be exactly the same as for Platform-owned , in the vendorID parameter you will have back the vendor ID that you passed creating.
Checkout with subscription
Once a plan is created, subscriptions can be attached to it. To proceed, initiate a Checkout Create request. This request generates a checkout UI (hosted or embedded), enabling the payer to either create a new payment method or select an existing one while providing their consent for the subscription. This ensures the subscription is successfully linked to the payer with an active payment method.
Make a POST/pay-ins/checkout request to create a checkout with subscription:
Example of a request payload
{
"country": "GB",
"plans": ["673edc4ffd8e7747e7a4473d"],
"paymentMethods": [
"creditCard"
],
"consumer": {
"reference": "12312123",
"name": "John Doe",
"email": "[email protected]"
},
"successfulPaymentRedirect": "https://platform.com/redirect"
}
Name | Type | Required | Description |
---|---|---|---|
plans | Array | Yes | |
paymentMethods | Array | No | |
consumer.reference | String | Yes | |
consumer.name | String | No | |
consumer.email | String | No | |
successfulPaymentRedirect | String | No | |
country | String | Yes | ISO31661 Alpha2 code |
Response
{
"status": "open",
"mode": "online",
"plans": [
{
"id": "673edc4ffd8e7747e7a4473d"
}
],
"isMoto": false,
"id": "6746f948926d3ebccc3ff124",
"country": "GB",
"successfulPaymentRedirect": "https://platform.com/redirect",
"amount": 100,
"currency": "GBP",
"totalAmount": 100,
"totalPaid": 0,
"reference": "PL-84e9381261",
"expiresAt": "2025-05-26T10:49:43.000Z",
"shortLink": "https://sandbox-checkout.unipaas.com/j5VmCYq4mj/",
"merchantId": "61066db0630f4e359dc084e9",
"signedLinkId": "j5VmCYq4mj",
"items": [],
"createdAt": "2024-11-27T10:49:44.299Z",
"updatedAt": "2024-11-27T10:49:44.299Z",
"sessionToken": "string",
"qrPaymentLink": "https://sandbox-checkout.unipaas.com/platform/qr-code/generate?url=https://sandbox-checkout.unipaas.com/j5VmCYq4mj/",
"vendorId": "665ed212fcdf0cfec3c87e02",
"consumer": {
"email": "[email protected]",
"name": "John Doe",
"reference": "12312123"
}
}
Name | Description |
---|---|
shortLink | The URL for the hosted checkout page. |
sessionToken | A session token used for authorization in UI web embeds implementation. |
Hosted checkout page
To use our hosted checkout, save the provided link (shortLink
) and share it directly with payers. The hosted checkout will handle the UI logic, including displaying available payment methods, plan details, trial period and determining the flow based on whether the user is new or returning.
Subscription Checkout UI Web Embed
To use our checkout UI web embed, refer to the following documentation. The checkout UI web embed will manage the UI logic, including displaying available payment methods, handling plan details, and determining the flow based on whether the user is new or returning.
As part of the checkout UI web embed implementation, you will need to handle DOM events as outlined in the documentation.
Subscription creation via API
You can use the API to create a subscription for the existing plan directly without requiring user involvement.
This method is applicable only if the subscription is intended for Direct Debit payment method and you already have an existing mandate set up with your user/customer through UNIPaaS.
Make a POST/pay-ins/plans/{planId}/subscriptions request to create a new Direct Debit subscription:
Example of a request payload
{
"paymentOptionId": "string"
}
You’ll need to provide the Plan ID and the Payment Option ID (obtained when creating a mandate through UNIPaaS with your user/customer).
Plan update
You can update your plan details, including the Plan Name, Plan Description, and Status. Updating the Status allows you to transition the plan between different statuses as outlined here.
Make a PATCH/pay-ins/plans/{planId} request to update plan details:
Example of a request payload
{
"name": "string",
"description": "string",
"status": "string"
}
Name | Description |
---|---|
status | Available statuses are:active , paused ,archived |
Additionally, you can manually change the statuses of plans using the Platform portal (from the Plans table).
Subscription update
You can update the status of an existing subscription using the API. This allows you to manage the subscription lifecycle efficiently, such as transitioning between active, paused, or canceled states as outlined here.
Make a PATCH/pay-ins/plans/{planId}/subscriptions/{subscriptionId} request to update subscription:
{
"status": "string"
}
Name | Description |
---|---|
status | Available statuses are: enabled , onHold , cancelled |
For manual updates, use the Platform portal to manage subscription statuses via the Subscriptions table.
Updated 11 days ago