Subscriptions work well for businesses that offer a monthly service. Rapyd Collect helps you integrate this functionality into your website or application.
This use case describes a regular monthly billing with the amount always the same.
- For periodic billing with the amount based on usage, or different rate levels depending on quantity, see Plan - Collect.
- For periodic billing with a fixed end date, see Subscription - Collect.
A customer would like to use your digital service, Acme Music, in Singapore. The cost is 3 Singapore dollars per month, indefinitely.
Summary
Prerequisite: A customer profile with a payment method defined.
Part 1 - Create Product of type 'service'.
Part 2 - Create Plan to define the pricing structure.
Part 3 - Create Subscription
Subscription Creation Workflow
Let’s look at the highlights of your workflow.
Prerequisite
A customer profile is created only one time. It contains payment methods that can be reused for all subsequent payments. It can be used for recurring payments and many other purposes.
Part 1 - Select a Payment Method

- Your website queries Rapyd for the payment methods available in Singapore.
- Rapyd returns a list of payment methods.
- Your website offers a list of choices to your customer.
Part 2 - Create a Customer Profile

- The customer selects your product and a payment method.
- Your website back end asks Rapyd to create a customer profile.
- Rapyd creates the profile and assigns a unique ID.
Steps
Step 1 - Create a Product

- You define the product you are providing.
- Your website back end asks Rapyd to create a product of type 'service'.
- Rapyd creates the product and returns a Product ID.
Step 2 - Create a Plan

- You determine the pricing structure you want for the recurring payment.
- Your website back end asks Rapyd to create the plan.
- Rapyd creates the plan and returns a Plan ID.
Step 3 - Create the Subscription

- You decide the parameters you need for the recurring payment.
- Your website back end asks Rapyd to create a subscription for the customer.
- Rapyd creates the subscription and returns a Subscription ID.
At the end of each billing period, Rapyd collects the amount due and adds it to your wallet.
How It Works
Prerequisite
Note
If you already have a customer with a payment method, you can skip to Create Product.
Find Payment Methods
First, you need to determine which Singaporean payment methods support payments in Singapore dollars (SGD). Run List Payment Methods by Country with the following parameters:
Query Parameter | Description |
---|---|
country | SG, the country code for Singapore. |
currency | SGD, the currency code for Singapore dollars. |
'List Payment Methods by Country' Request
// Request URL: GET https://sandboxapi.rapyd.net/v1/payment_methods/country?country=SG¤cy=SGD
// Message body absent
using System;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
string country = "SG";
string currency = "SGD";
string result = RapydApiRequestSample.Utilities.MakeRequest("GET", $"/v1/payment_methods/country?country={country}¤cy={currency}");
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const result = await makeRequest(
'GET',
'/v1/payment_methods/country?country=SG¤cy=SGD
);
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
try {
$object = make_request('get', '/v1/payment_methods/country?country=SG¤cy=SGD');
echo $object;
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
country = 'SG'
currency = 'SGD'
results = make_request(method='get',
path=f'/v1/payment_methods/country?country={country}¤cy={currency}')
pprint(results)
'List Payment Methods by Country' Response
Rapyd returns the following response (redacted for brevity). The fields are described in Payment Method Type Object.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "865cd976-1b2f-4321-b88c-3caaa5a4499e"
},
"data": [
{
"type": "sg_credit_cup_card",
"name": "UnionPay",
"category": "card",
"image": "https://iconslib.rapyd.net/checkout/sg_credit_cup_card.png",
"country": "sg",
"payment_flow_type": "",
"currencies": [
"SGD"
],
"status": 1,
"is_cancelable": true,
"payment_options": [
{
"name": "capture",
"type": "boolean",
"regex": "",
"description": "Determines when the payment is processed for capture.",
"is_required": false,
"is_updatable": false
},
{
"name": "complete_payment_url",
"type": "string",
"regex": "",
"description": "the complete_payment_url field must be filled in.",
"is_required": true,
"is_updatable": false
},
{
"name": "error_payment_url",
"type": "string",
"regex": "",
"description": "the error_payment_url field must be filled in.",
"is_required": true,
"is_updatable": false
},
{
"name": "statement_descriptor",
"type": "string",
"regex": "/^[a-zA-Z0-9]{0,22}/",
"description": "A text description suitable for a customer's payment statement. Limited to 22 characters.",
"is_required": false,
"is_updatable": false
}
],
"is_expirable": false,
"is_online": false,
"is_refundable": true,
"minimum_expiration_seconds": 0,
"maximum_expiration_seconds": 604800,
"virtual_payment_method_type": "card",
"is_virtual": false,
"multiple_overage_allowed": false,
"amount_range_per_currency": [
{
"currency": "SGD",
"maximum_amount": null,
"minimum_amount": null
}
],
"is_tokenizable": false,
"supported_digital_wallet_providers": [],
"submid_required": false,
"is_restricted": false
},
// . . .
]
}
Using your website or a Rapyd hosted page, you display one or more of these payment methods to the customer. The customer chooses one and provides the required information.
Get Required Fields
Each payment method has its own requirements. To determine what information the customer needs to provide, run Get Payment Method Required Fields. In this use case, our customer chose UnionPay.
Path Parameter | Description |
---|---|
type | sg_credit_cup_card, the ID for the UnionPay payment method type. |
'Get Payment Method Required Fields' Request
// Request URL: GET https://sandboxapi.rapyd.net/v1/payment_methods/required_fields/sg_credit_cup_card
// Message body absent
using System;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
string type = "sg_fast_bank";
string result = RapydApiRequestSample.Utilities.MakeRequest("GET", $"/v1/payment_methods/required_fields/{type}");
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const result = await makeRequest('GET', '/v1/payment_methods/required_fields/sg_fast_bank');
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
try {
$object = make_request('get', '/v1/payment_methods/required_fields/sg_fast_bank');
echo $object;
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
payment_method = 'sg_fast_bank'
results = make_request(method='get',
path=f'/v1/payment_methods/required_fields/{payment_method}')
pprint(results)
'Get Payment Method Required Fields' Response
Rapyd returns the following response. The fields in the response are described in Payment Method Type Object.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "01ccc669-ca5d-4ff4-bc1e-88be05fae2cb"
},
"data": {
"type": "sg_credit_cup_card",
"fields": [
{
"name": "name",
"type": "string",
"regex": "",
"is_required": true,
"instructions": "card holder name"
},
{
"name": "number",
"type": "string",
"regex": "",
"is_required": true,
"instructions": "card number"
},
{
"name": "expiration_month",
"type": "string",
"regex": "",
"is_required": true,
"instructions": "expiration month as string, 01-12"
},
{
"name": "expiration_year",
"type": "string",
"regex": "",
"is_required": true,
"instructions": "expiration year in to digits as string, 18-99"
},
{
"name": "cvv",
"type": "string",
"regex": "",
"is_required": true,
"instructions": "card cvv"
}
],
"payment_method_options": [
{
"name": "3d_required",
"type": "boolean",
"regex": "",
"description": "Allows the client to determine whether the customer is required to complete 3DS authentication for the transaction",
"is_required": false,
"is_updatable": false
}
],
"payment_options": [
{
"name": "capture",
"type": "boolean",
"regex": "",
"description": "Determines when the payment is processed for capture.",
"is_required": false,
"is_updatable": false
},
{
"name": "complete_payment_url",
"type": "string",
"regex": "",
"description": "the complete_payment_url field must be filled in.",
"is_required": true,
"is_updatable": false
},
{
"name": "error_payment_url",
"type": "string",
"regex": "",
"description": "the error_payment_url field must be filled in.",
"is_required": true,
"is_updatable": false
},
{
"name": "statement_descriptor",
"type": "string",
"regex": "/^[a-zA-Z0-9]{0,22}/",
"description": "A text description suitable for a customer's payment statement. Limited to 22 characters.",
"is_required": false,
"is_updatable": false
}
],
"minimum_expiration_seconds": 0,
"maximum_expiration_seconds": 604800
}
}
The response shows that this payment method does not require any specific fields or payment method options.
Note
Some payment methods require fields in the 'payment_options' array to appear in other contexts. For details, see the description of the fields in the response to 'Get Payment Method Required Fields'.
Create Customer Profile
Create the customer's profile with all parameters required for a customer and for the payment method selected. For our example, we will use Create Customer with the following parameters:
Body Parameter | Description |
---|---|
name | Your customer's name. |
Your customer's email address. | |
payment_method | An object containing the following: * type - string - The code for the payment method, in this case, sg_credit_cup_card.* fields - object - The fields required for the payment method, as shown in the fields array in the response to Get Payment Method Required Fields. |
Note
If you are creating a card payment method and you do not have PCI clearance, you must create the customer without the payment method, then add the payment method using Create Card Token, then set that payment method as the default with Update Customer.
// Request URL: post https://sandboxapi.rapyd.net/v1/customers
// Message body
{
"name": "John Doe",
"email": "[email protected]",
"payment_method": {
"type": "sg_credit_cup_card",
"fields": {
"number": "4111111111111111",
"expiration_month": "10",
"expiration_year": "23",
"cvv": "123",
"name": "John Doe"
},
"complete_payment_url": "https://complete.rapyd.net/",
"error_payment_url": "https://error.rapyd.net/"
}
}
using System;
using System.Text.Json;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
var requestObj = new
{
name = "John Doe",
email = "[email protected]",
payment_method = new Object[]
{
new
{
type = "sg_credit_cup_card",
fields = new Object[]
{
new
{
number = "4111111111111111",
expiration_month = "10",
expiration_year = "23",
cvv = "123",
name = "John Doe"
}
}
complete_payment_url = "https://complete.rapyd.net/",
error_payment_url = "https://error.rapyd.net/"
}
}
};
string request = JsonSerializer.Serialize(requestObj);
string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/customers", request);
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const body = {
name: 'John Doe',
email: '[email protected]',
payment_method: [
{
type: 'sg_credit_cup_card',
fields: [
number: '4111111111111111',
expiration_month: '10',
expiration_year: '23',
cvv: '123',
name: 'John Doe'
],
complete_payment_url: 'https://complete.rapyd.net/',
error_payment_url: 'https://error.rapyd.net/'
}
]
};
const result = await makeRequest('POST', '/v1/customers', body);
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
$body = [
"name" => "John Doe",
"email" => "[email protected]",
"payment_method" => array(array(
"type" => "sg_credit_cup_card",
"fields" => array(array(
"number" => "4111111111111111",
"expiration_month" => "10",
"expiration_year" => "23",
"cvv" => "123",
"name" => "John Doe"
)),
"complete_payment_url" => "https://complete.rapyd.net/",
"error_payment_url" => "https://error.rapyd.net/"
))
];
try {
$object = make_request('post', '/v1/customers', $body);
var_dump($object);
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
customer = {
"name": "John Doe",
"email": "[email protected]",
"payment_method": {
"type": "sg_credit_cup_card",
"fields": {
"number": "4111111111111111",
"expiration_month": "10",
"expiration_year": "23",
"cvv": "123",
"name": "John Doe"
},
"complete_payment_url": "https://complete.rapyd.net/",
"error_payment_url": "https://error.rapyd.net/"
}
}
result = make_request(method='post',
path='/v1/customers',
body=customer)
pprint(result)
'Create Customer' Response
Rapyd returns the following response. The fields are described in Customer Object and Payment Method Type Object.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "acc384b0-1430-4d7d-a2b0-327be9da975a"
},
"data": {
"id": "cus_81da79bf18af36e64b49c1c374faa524",
"delinquent": false,
"discount": null,
"name": "John Doe",
"default_payment_method": "card_c01d1b10f309884f381cfc499cdfb1ec",
"description": "",
"email": "[email protected]",
"phone_number": "",
"invoice_prefix": "",
"addresses": [],
"payment_methods": {
"data": [
{
"id": "card_c01d1b10f309884f381cfc499cdfb1ec",
"type": "sg_credit_cup_card",
"category": "card",
"metadata": null,
"image": "https://iconslib.rapyd.net/checkout/sg_credit_cup_card.png",
"webhook_url": "",
"supporting_documentation": "",
"next_action": "3d_verification",
"name": "John Doe",
"last4": "1111",
"acs_check": "unchecked",
"cvv_check": "unchecked",
"bin_details": {
"type": null,
"brand": null,
"level": null,
"country": null,
"bin_number": "411111"
},
"expiration_year": "23",
"expiration_month": "10",
"fingerprint_token": "ocfp_e599f990674473ce6283b245e9ad2467",
"redirect_url": "https://sandboxcheckout.rapyd.net/3ds-payment?token=payment_178af04b589334ee6406eee7a430e028"
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/customers/cus_81da79bf18af36e64b49c1c374faa524/payment_methods"
},
"subscriptions": null,
"created_at": 1668353979,
"metadata": {},
"business_vat_id": "",
"ewallet": "",
"network_reference_id": 962926,
"complete_payment_url": "https://complete.rapyd.net/",
"error_payment_url": "https://error.rapyd.net/"
}
}
Create Product
To define a product of type services, run Create Product with the following parameters:
Body Parameter | Description |
---|---|
name | Enter the name of your product, Acme Music Stream. |
type | Enter services. |
'Create Product' Request
// Request URL: POST https://sandboxapi.rapyd.net/v1/products
// Message body:
{
"name": "Acme Music Stream",
"type": "services"
}
using System;
using System.Text.Json;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
var requestObj = new
{
name = "Acme Music Stream",
type = "services",
};
string request = JsonSerializer.Serialize(requestObj);
string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/products", request);
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const body = {
name: 'Acme Music Stream',
type: 'services'
};
const result = await makeRequest('POST', '/v1/products', body);
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
$body = [
"name" => "Acme Music Stream",
"type" => "services"
];
try {
$object = make_request('post', '/v1/products', $body);
var_dump($object);
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
product = {
"name": "Acme Music Stream",
"type": "services"
}
results = make_request(method='post',
path=f'/v1/products',
body=product)
pprint(results)
'Create Product' Response
Rapyd returns the following response. The fields are described in Product Object - Collect.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "1f5c173f-fc9a-4d11-9fd3-de91419b5ab7"
},
"data": {
"id": "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"active": true,
"attributes": [],
"created_at": 1668432691,
"description": "",
"images": [],
"metadata": {},
"name": "Acme Music Stream",
"package_dimensions": {
"height": 0,
"length": 0,
"weight": 0,
"width": 0
},
"shippable": false,
"skus": [],
"statement_descriptor": "",
"type": "services",
"unit_label": "",
"updated_at": 1668432691
}
}
The data
section of this response shows that:
- The product
id
for your product is product_3f22f9ef6eb18894e95127e5bb8e0c9d. When you run this example in your own sandbox, you will get a different ID, which you will need for the next step. - The product
name
is Acme Music Stream. - The product
type
is services.
Create Plan
The plan defines the pricing structure for your product. You can define different plans for the same product, for example, basic or premium, with different rates. For this use case, run Create Plan with the following parameters:
Body Parameter | Description |
---|---|
amount | Enter 3.00 as the monthly amount for the plan. |
currency | Enter SGD as the currency code for Singapore dollar. |
interval | Enter month as the billing cycle interval. |
product | Enter the ID that you received when you created the product in your sandbox. In this instance, we are using product_3f22f9ef6eb18894e95127e5bb8e0c9d, which is for the product we created in our sandbox. |
nickname | Enter Basic Streaming as the name of the plan. |
usage_type | Enter licensed as the usage type. The customer is billed a flat rate, even when the service is not used. For other options, see Plan - Collect. |
'Create Plan' Request
// Request URL: POST https://sandboxapi.rapyd.net/v1/plans
// Message body
{
"currency": "SGD",
"interval": "month",
"product": "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"amount": 3,
"nickname": "Basic Streaming",
"usage_type": "licensed"
}
using System;
using System.Text.Json;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
var requestObj = new
{
currency = "SGD",
interval = "month",
product = "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
amount = 3,
nickname = "Basic Streaming",
usage_type = "licensed",
};
string request = JsonSerializer.Serialize(requestObj);
string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/plans", request);
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const body = {
currency: 'SGD',
interval: 'month',
product: 'product_3f22f9ef6eb18894e95127e5bb8e0c9d',
amount: 3,
nickname: 'Basic Streaming',
usage_type: 'licensed'
};
const result = await makeRequest('POST', '/v1/plans', body);
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
$body = [
"currency" => "SGDSGD",
"interval" => "month",
"product" => "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"amount" => 3,
"nickname" => "Basic Streaming",
"usage_type" => "licensed"
];
try {
$object = make_request('post', '/v1/plans', $body);
var_dump($object);
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
# Create Plan request
plan = {
"currency": "SGD",
"interval": "month",
"product": "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"amount": 3,
"nickname": "Basic Streaming",
"usage_type": "licensed"
}
result = make_request(method='post',
path='/v1/plans',
body=plan)
pprint(result)
'Create Plan' Response
Rapyd returns the following response. The fields are described in Plan Object - Collect.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "935d04de-51b9-4869-a68c-76692ce5387a"
},
"data": {
"id": "plan_5487c8a5be1dd847de7da4ce8feebfab",
"aggregate_usage": "sum",
"amount": 3,
"billing_scheme": "per_unit",
"created_at": 1668432810,
"currency": "SGD",
"interval": "month",
"interval_count": 1,
"metadata": {},
"product": {
"id": "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"active": true,
"attributes": [],
"created_at": 1668432691,
"description": "",
"images": [],
"metadata": {},
"name": "Acme Music Stream",
"package_dimensions": {
"height": 0,
"length": 0,
"weight": 0,
"width": 0
},
"shippable": false,
"skus": [],
"statement_descriptor": "",
"type": "services",
"unit_label": "",
"updated_at": 1668432691
},
"nickname": "Basic Streaming",
"tiers": [],
"tiers_mode": "",
"transform_usage": {
"divide_by": 1,
"round": "up"
},
"trial_period_days": 0,
"usage_type": "licensed"
}
}
The data section of this response shows that Rapyd created an ID for the Basic Streaming plan and linked it to the product. The ID of the plan is plan_5487c8a5be1dd847de7da4ce8feebfab. When you run this example in your own sandbox, you get a different ID, which you will need for the next step.
Create Subscription
The final step in the process is creating the subscription itself. Here, you link all the required elements together: (customer, product, the plan) and set the subscription to continue indefinitely. To make the subscription terminate at a specific time, see Subscription Object - Collect. This use case uses the API, but you can create the subscription with a hosted page. See Create Subscription by Create Subscription by Hosted Page.
Run Create Subscription with the following parameters:
Body Parameter | Description |
---|---|
customer | Enter the ID that you received when you created the customer in your sandbox. In this instance, we are using cus_81da79bf18af36e64b49c1c374faa524, which is the ID of the customer we created in our sandbox. Because we are not explicitly mentioning a payment method, the API will use the customer's default payment method. To use a payment method other than the default, configure payment_method . See Subscription Object - Collect. |
billing | Enter pay_automatically. |
subscription_items | Enter an array that contains only one object. The object contains the following fields: ● plan - Enter the plan 'id' that you received when you created the plan in your sandbox. In this instance, we are using plan_5487c8a5be1dd847de7da4ce8feebfab, which is the plan ID we created for our sandbox.● quantity - Enter 1, since your customer is subscribing to one instance of this plan (for example). |
'Create Subscription' Request
Request Rapyd to create a subscription for your customer.
// Request URL: POST /v1/payments/subscriptions/
// Message body:
{
"customer": "cus_81da79bf18af36e64b49c1c374faa524",
"billing": "pay_automatically",
"subscription_items": [
{
"plan": "plan_5487c8a5be1dd847de7da4ce8feebfab",
"quantity": 1
}
]
}
using System;
using System.Text.Json;
namespace RapydApiRequestSample
{
class Program
{
static void Main(string[] args)
{
try
{
var requestObj = new
{
customer = "cus_81da79bf18af36e64b49c1c374faa524",
billing = "pay_automatically",
subscription_items = new Object[]
{
new
{
plan = "plan_5487c8a5be1dd847de7da4ce8feebfab",
quantity = 1
}
}
};
string request = JsonSerializer.Serialize(requestObj);
string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/payments/subscriptions", request);
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine("Error completing request: " + e.Message);
}
}
}
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
async function main() {
try {
const body = {
customer: 'cus_81da79bf18af36e64b49c1c374faa524',
billing: 'pay_automatically',
subscription_items: [
{
plan: 'plan_5487c8a5be1dd847de7da4ce8feebfab',
quantity: 1
}
]
};
const result = await makeRequest('POST', '/v1/payments/subscriptions', body);
console.log(result);
} catch (error) {
console.error('Error completing request', error);
}
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);
$body = [
"customer" => "cus_81da79bf18af36e64b49c1c374faa524",
"billing" => "pay_automatically",
"subscription_items" => array(array(
"plan" => "plan_5487c8a5be1dd847de7da4ce8feebfab",
"quantity" => 1
))
];
try {
$object = make_request('post', '/v1/payments/subscriptions', $body);
var_dump($object);
} catch (Exception $e) {
echo "Error: $e";
}
?>
from pprint import pprint
from utilities import make_request
subscription = {
"customer": "cus_81da79bf18af36e64b49c1c374faa524",
"billing": "pay_automatically",
"subscription_items": [
{
"plan": "plan_5487c8a5be1dd847de7da4ce8feebfab",
"quantity": 1
}
]
}
result = make_request(method='post',
path='/v1/payments/subscriptions',
body=subscription)
pprint(result)
'Create Subscription' Response
Rapyd returns the following response. The fields are described in Subscription Object - Collect.
{
"status": {
"error_code": "",
"status": "SUCCESS",
"message": "",
"response_code": "",
"operation_id": "423028d6-5bc5-429d-9d59-049a3967ccfa"
},
"data": {
"id": "sub_c1388d28c46c4cf853655a5a822e5e46",
"billing": "pay_automatically",
"billing_cycle_anchor": 1668432892,
"created_at": 1668432892,
"customer_token": "cus_81da79bf18af36e64b49c1c374faa524",
"days_until_due": 30,
"metadata": {},
"tax_percent": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"current_period_end": 1671024892,
"current_period_start": 1668432892,
"discount": null,
"ended_at": null,
"subscription_items": {
"data": [
{
"id": "subi_b4b55ddb6c854be912cceeb4d95ed1a4",
"created": 1668432892,
"metadata": null,
"quantity": 1,
"plan": {
"id": "plan_5487c8a5be1dd847de7da4ce8feebfab",
"aggregate_usage": "sum",
"amount": 3,
"billing_scheme": "per_unit",
"created_at": 1668432810,
"currency": "SGD",
"interval": "month",
"interval_count": 1,
"metadata": {},
"product": "product_3f22f9ef6eb18894e95127e5bb8e0c9d",
"nickname": "Basic Streaming",
"tiers": [],
"tiers_mode": "",
"transform_usage": {
"divide_by": 1,
"round": "up"
},
"trial_period_days": 0,
"usage_type": "licensed"
}
}
],
"has_more": false,
"total_count": 0,
"url": "/v1/subscription_items?subscription=sub_c1388d28c46c4cf853655a5a822e5e46"
},
"status": "active",
"trial_end": null,
"trial_start": null,
"payment_method": "card_c01d1b10f309884f381cfc499cdfb1ec",
"payment_fields": null,
"payout_fields": null,
"type": "payment"
}
}
The data section of this response shows:
- The
id
of the subscription is sub_c1388d28c46c4cf853655a5a822e5e46. When you run this example in your own sandbox, you will get a different ID. - The customer's payment method will be charged 3.00 SGD every month until the subscription is canceled.
Updated 2 months ago
What's Next
Mass Invoices |