Skip to main content

Documentation

Subscriptions

With Rapyd Collect, you can create subscriptions (also called subscription billing, recurring billing or recurring payments).

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.

  • For periodic billing with a fixed end date, see Create Subscription.

A customer would like to use your digital service, Acme Music, in Singapore. The cost is 3 Singapore dollars per month, indefinitely.

Part 1 - Create Product of type 'service'.

Part 2 - Create Plan to define the pricing structure.

Part 3 - Create Subscription

Note: A customer profile with a payment method defined is needed to create a subscription.

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
643e7dbfb8223.png
  1. Your website queries Rapyd for the payment methods available in Singapore.

  2. Rapyd returns a list of payment methods.

  3. Your website offers a list of choices to your customer.

Part 2 - Create a Customer Profile
643e7dc13588f.png
  1. The customer selects your product and a payment method.

  2. Your website back end asks Rapyd to create a customer profile.

  3. Rapyd creates the profile and assigns a unique ID.

Step 1 - Create a Product
643e7dc299474.png
  1. You define the product you are providing.

  2. Your website back end asks Rapyd to create a product of type 'service'.

  3. Rapyd creates the product and returns a Product ID.

Step 2 - Create a Plan
643e7dc3c28d2.png
  1. You determine the pricing structure you want for the recurring payment.

  2. Your website back end asks Rapyd to create the plan.

  3. Rapyd creates the plan and returns a Plan ID.

Step 3 - Create the Subscription
643e7dc5213bb.png
  1. You decide the parameters you need for the recurring payment.

  2. Your website back end asks Rapyd to create a subscription for the customer.

  3. 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.

The message sequence diagrams below describe how information is exchanged between Rapyd, the merchant, and the card network.

Create Subscription

subscription-with-automatic-capture-of-card-payment.svg

Customer ID with Saved Payment Method

If you already have a customer with a payment method, you can skip to Create Product.

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:

Description of Query 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

      • // Request URL: GET https://sandboxapi.rapyd.net/v1/payment_methods/country?country=SG&currency=SGD
        
        // Message body absent
    • .NET Core

      • 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}&currency={currency}");
        
                        Console.WriteLine(result);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error completing request: " + e.Message);
                    }
                }
            }
         }
    • JavaScript

      • 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&currency=SGD
            );
        
            console.log(result);
          } catch (error) {
            console.error('Error completing request', error);
          }
        }
        
    • PHP

      • <?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&currency=SGD');
            echo $object;
        } catch (Exception $e) {
            echo "Error: $e";
        }
        ?>
    • Python

      • 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}&currency={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 .

    • Response

      • {
            "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.

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.

Description of Path Parameters

Path Parameter

Description

type

sg_credit_cup_card, the ID for the UnionPay payment method type.

Get Payment Method Required Fields Request
    • Request

      • // Request URL: GET https://sandboxapi.rapyd.net/v1/payment_methods/sg_credit_cup_card/required_fields
        
        // Message body absent
    • .NET Core

      • 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/{type}/required_fields");
        
                        Console.WriteLine(result);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error completing request: " + e.Message);
                    }
                }
            }
        }
    • JavaScript

      • const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
        
        async function main() {
          try {
            const result = await makeRequest('GET', '/v1/payment_methods/sg_fast_bank/required_fields');
        
            console.log(result);
          } catch (error) {
            console.error('Error completing request', error);
          }
        }
    • PHP

      • <?php
        $path = $_SERVER['DOCUMENT_ROOT'];
        $path .= "/<path-to-your-utility-file>/utilities.php";
        include($path);
        
        try {
            $object = make_request('get', '/v1/payment_methods/sg_fast_bank/required_fields');
            echo $object;
        } catch (Exception $e) {
            echo "Error: $e";
        }
        ?>
    • Python

      • from pprint import pprint
        
        from utilities import make_request
        
        payment_method = 'sg_fast_bank'
        results = make_request(method='get',
                               path=f'/v1/payment_methods/{payment_method}/required_fields')
        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 .

    • Response

      • {
            "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 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:

Description of Body Parameters

Body Parameter

Description

name

Your customer's name.

email

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.

Create Customer Request
    • Request

      • // Request URL: post https://sandboxapi.rapyd.net/v1/customers
        
        // Message body
        {
            "name": "John Doe",
            "email": "johndoe@rapyd.net",
            "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/"
            }
        }
        
    • .NET Core

      • using System;
         using System.Text.Json;
        
         namespace RapydApiRequestSample
         {
            class Program
            {
                static void Main(string[] args)
                {
                    try
                    {
                        var requestObj = new
                        {
                            name = "John Doe",
                            email = "johndoe@rapyd.net",
                            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);
                    }
                }
            }
         }
    • JavaScript

      • const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;
        
        async function main() {
          try {
            const body = {
              name: 'John Doe',
              email: 'johndoe@rapyd.net',
              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

      • <?php
        $path = $_SERVER['DOCUMENT_ROOT'];
        $path .= "/<path-to-your-utility-file>/utilities.php";
        include($path);
        
        $body = [
            "name" => "John Doe",
            "email" => "johndoe@rapyd.net",
            "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";
        }
        ?>
    • Python

      • from pprint import pprint
        
        from utilities import make_request
        
        customer = {
            "name": "John Doe",
            "email": "johndoe@rapyd.net",
            "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.

    • Response

      • {
            "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": "johndoe@rapyd.net",
                "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/"
            }
        }

To define a product of type services, run Create Product with the following parameters:

Description of Body Parameters

Body Parameter

Description

name

Enter the name of your product, Acme Music Stream.

type

Enter services .

Create Product Request
    • Request

      • // Request URL: POST https://sandboxapi.rapyd.net/v1/products
        
        // Message body: 
        {
          "name": "Acme Music Stream",
          "type": "services"
        }
    • .NET Core

      • 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);
                    }
                }
            }
         }
    • JavaScript

      • 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

      • <?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";
        }
        ?>
    • Python

      • 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.

    • Response

      • {
            "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.

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:

Description of Body 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 Create Plan.

Create Plan Request
    • 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"
        }
        
    • .NET Core

      • 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);
                    }
                }
            }
         }
    • JavaScript

      • 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

      • <?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";
        }
        ?>
    • Python

      • 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.

    • Response

      • {
            "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.

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. 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:

Description of Body 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.

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

      • // Request URL: POST /v1/payments/subscriptions/
        
        // Message body: 
        {
                "customer": "cus_81da79bf18af36e64b49c1c374faa524",
                "billing": "pay_automatically",
                "subscription_items": [
            {
                                "plan": "plan_5487c8a5be1dd847de7da4ce8feebfab",
                                "quantity": 1
                        }
                ]
        }
    • .NET Core

      • 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);
                    }
                }
            }
         }
    • JavaScript

      • 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

      • <?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";
        }
        ?>
    • Python

      • 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.

    • Response

      • {
            "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.