subscriptions

Subscriptions Integration

To integrate the Subscriptions API, first set up your development environment and then create a product, plan, and subscription.

Availability: Customers who integrated with Subscriptions before April 2019 can access reference and support material in the archived Subscriptions integration guide.

Note: This integration is not supported for merchants in the gambling category.

1. Set up your development environment

Before you can integrate Subscriptions, you must set up your development environment. After you get a token that lets you access protected REST API resources, you create sandbox accounts to test your web and mobile apps. For details, see Get Started.

Then, return to this page to integrate Subscriptions.

2. Create a product

A product captures goods or services offered for a subscription.

Note: This is a one time operation.

The <ID> is either merchant-provided or system-generated and begins with PROD-xxxx.

Create your product by calling /products:

curl -v -X POST https://api.sandbox.paypal.com/v1/catalogs/products \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -H "PayPal-Request-Id: merchant-generated-ID \ // Optional and if passed, helps identify idempotent requests
-d '{
  "name": "Video Streaming Service",
  "description": "Video streaming service",
  "type": "SERVICE",
  "category": "SOFTWARE",
  "image_url": "https://example.com/streaming.jpg",
  "home_url": "https://example.com/home"
}'

A successful request returns the HTTP 201 Created status code with a JSON response body.

{
  "id": "PROD-XYAB12ABSB7868434",
      "name": "Video Streaming Service",
      "description": "Video streaming service",
      "type": "SERVICE",
      "category": "SOFTWARE",
      "image_url": "https://example.com/streaming.jpg",
      "home_url": "https://example.com/home",
      "create_time": "2019-01-10T21:20:49Z",
      "update_time": "2019-01-10T21:20:49Z",
      "links": [
        {
          "href": "https://api.paypal.com/v1/catalogs/products/72255d4849af8ed6e0df1173",
          "rel": "self",
          "method": "GET"
        },
        {
          "href": "https://api.paypal.com/v1/catalogs/products/72255d4849af8ed6e0df1173",
          "rel": "edit",
          "method": "PATCH"
        }
      ]
}

If creating a product succeeds, it triggers the CATALOG.PRODUCT.CREATED webhook.

3. Create a plan

You can associate multiple plans to a product. For example, a video streaming service can have several plans: trial, basic, standard, and premium.

You can create either a finite plan or an infinite plan:

  • Finite Plan - A plan with a fixed number of cycles. Once a buyer subscribes, a finite plan expires after the total number of cycles defined for are completed. For example, a buyer can subscribe to an online tutorial service for 3 cycles.
  • Infinite Plan - A plan without a fixed number of cycles. Once a buyer subscribes, an infinite plan remains active until cancelation. For example, a buyer can subscribe to a video or music streaming service with no specified end date.

A trial period plan is useful to let your subscriber try your product at a free or discounted price before regular billing cycles start.

Note: Creating a plan is a one time operation.

Create a plan by calling /plans. Plans are active by default.

This sample request creates a trial plan with a fixed pricing scheme. For quantity (user or seat) based pricing plans, set the quantity_supported attribute to true to indicate that customers can subscribe to this plan by providing the number of units they what to subscribe to.

curl -v -k -X POST https://api.sandbox.paypal.com/v1/billing/plans \
  -H "Accept: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -H "PayPal-Request-Id: PLAN-18062019-001" \  // merchant generated ID, optional and needed for idempotent samples
  -H "Prefer: return=representation" \
  -H "Content-Type: application/json" \
  -d '{
      "product_id": "PROD-6XB24663H4094933M",
      "name": "Basic Plan",
      "description": "Basic plan",
      "billing_cycles": [
        {
          "frequency": {
            "interval_unit": "MONTH",
            "interval_count": 1
          },
          "tenure_type": "TRIAL",
          "sequence": 1,
          "total_cycles": 1
        },
        {
          "frequency": {
            "interval_unit": "MONTH",
            "interval_count": 1
          },
          "tenure_type": "REGULAR",
          "sequence": 2,
          "total_cycles": 12,
          "pricing_scheme": {
            "fixed_price": {
              "value": "10",
              "currency_code": "USD"
            }
          }
        }
      ],
      "payment_preferences": {
        "auto_bill_outstanding": true,
        "setup_fee": {
          "value": "10",
          "currency_code": "USD"
        },
        "setup_fee_failure_action": "CONTINUE",
        "payment_failure_threshold": 3
      },
      "taxes": {
        "percentage": "10",
        "inclusive": false
      }
    }'
curl -v -k -X POST https://api.sandbox.paypal.com/v1/billing/plans \
  -H "Accept: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -H "PayPal-Request-Id: PLAN-18062019-001" \  // merchant generated ID, optional and needed for idempotent samples
  -H "Prefer: return=representation" \
  -H "Content-Type: application/json" \
  -d '{
        "product_id": "PROD-XXCD1234QWER65782",
        "name": "Basic Plan",
        "description": "Basic plan",
        "billing_cycles": [
          {
            "frequency": {
                "interval_unit": "MONTH",
                "interval_count": 1
            },
            "tenure_type": "TRIAL",
            "sequence": 1,
            "total_cycles": 1
          },
            {
              "frequency": {
                "interval_unit": "MONTH",
                "interval_count": 1
              },
              "tenure_type": "REGULAR",
              "sequence": 2,
              "total_cycles": 12,
              "pricing_scheme": {
                "fixed_price": {
                  "value": "10",
                  "currency_code": "USD"
                }
              }
            }
          ],
        "payment_preferences": {
          "service_type": "PREPAID",
          "auto_bill_outstanding": true,
          "setup_fee": {
            "value": "10",
            "currency_code": "USD"
          },
          "setup_fee_failure_action": "CONTINUE",
          "payment_failure_threshold": 3
        },
        "quantity_supported": true,
        "taxes": {
          "percentage": "10",
          "inclusive": false
        }
    }'

A successful request returns the HTTP 201 Created status code with a JSON response body that shows subscription details.

{
  "id": "P-2UF78835G6983425GLSM44MA",
  "product_id": "PROD-6XB24663H4094933M",
  "name": "Basic Plan",
  "status": "ACTIVE",
  "description": "Basic plan",
  "billing_cycles": [
    {
      "frequency": {
        "interval_unit": "MONTH",
        "interval_count": 1
      },
      "tenure_type": "TRIAL",
      "sequence": 1,
      "total_cycles": 1
    },
    {
      "pricing_scheme": {
        "fixed_price": {
          "currency_code": "USD",
          "value": "10.00"
        }
      },
      "frequency": {
        "interval_unit": "MONTH",
        "interval_count": 1
      },
      "tenure_type": "REGULAR",
      "sequence": 2,
      "total_cycles": 12
    }
  ],
  "payment_preferences": {
    "auto_bill_outstanding": true,
    "setup_fee": {
      "currency_code": "USD",
      "value": "10.00"
    },
    "setup_fee_failure_action": "CONTINUE",
    "payment_failure_threshold": 3
  },
  "taxes": {
    "percentage": "10.00",
    "inclusive": false
  },
  "quantity_supported": false,
  "create_time": "2019-03-26T07:01:04Z",
  "update_time": "2019-03-26T07:01:04Z",
  "links": [
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA",
      "rel": "edit",
      "method": "PATCH"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA/deactivate",
      "rel": "self",
      "method": "POST"
        }
      ]
    }
{
  "id": "P-2UF78835G6983425GLSM44MA",
  "product_id": "PROD-XYAB12ABSB7868434",
  "name": "Basic Plan",
  "status": "ACTIVE",
  "description": "Basic plan",
  "billing_cycles": [
    {
      "frequency": {
        "interval_unit": "MONTH",
        "interval_count": 1
      },
      "tenure_type": "TRIAL",
      "sequence": 1,
      "total_cycles": 1
    },
    {
      "pricing_scheme": {
        "fixed_price": {
          "currency_code": "USD",
          "value": "10.0"
        }
      },
      "frequency": {
        "interval_unit": "MONTH",
        "interval_count": 1
      },
      "tenure_type": "REGULAR",
      "sequence": 2,
      "total_cycles": 12
    }
  ],
  "payment_preferences": {
    "auto_bill_outstanding": true,
    "setup_fee": {
      "currency_code": "USD",
      "value": "10.0"
    },
    "setup_fee_failure_action": "CONTINUE",
    "payment_failure_threshold": 3
  },
  "taxes": {
    "percentage": "10.0",
    "inclusive": false
  },
  "quantity_supported": false,
  "create_time": "2019-03-26T07:01:04Z",
  "update_time": "2019-03-26T07:01:04Z",
  "links": [
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA",
      "rel": "edit",
      "method": "PATCH"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA/deactivate",
      "rel": "self",
      "method": "POST"
    }
  ]
}

If creating a plan succeeds, it triggers the BILLING.PLAN.CREATED webhook.

4. Create a subscription

PayPal recommends using Subscriptions with Smart Payment Buttons as it gives your buyers a simplified and secure subscription experience. PayPal presents payment types to your buyers automatically, making it easier for them to complete their purchase using methods like Pay with Venmo, PayPal Credit, and credit card payments without reintegration as they are made available. You can also use the Subscriptions API.

Subscriptions with Smart Payment Buttons

To use Subscriptions with Smart Payment Buttons:

  1. Add the PayPal script to your web page.
  2. Render the Smart Payment Button.
  3. Create the subscription.

Add the PayPal script

Add the PayPal script to your web page and add your sandbox client_id to the script tag.

<!DOCTYPE html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>

<body>
  <script
       src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID&vault=true">
  </script>
</body>

Make sure you:

  • Add the <!DOCTYPE html> tag for optimal browser compatibility.
  • Add the <meta http-equiv="X-UA-Compatible" content="IE=edge" /> meta tag to the page for optimal Internet Explorer compatibility.
  • Add the <meta name="viewport" content="width=device-width, initial-scale=1"> tag to the page to ensure optimal rendering on mobile devices.

You can customize your integration by passing different query parameters to https://www.paypal.com/sdk/js

Option Example value Default Description
client-id sb required Your PayPal REST client ID. This identifies your PayPal account and determines where transactions are paid to. While you're testing in sandbox, you can use client-id=sb as a shortcut.
vault true, false false Set to true for subscriptions.

See Customize the SDK for a complete list of available parameters and values.

Render the Smart Payment Button

Next, render the PayPal Smart Payment Buttons to a container element on your page.

<body>
  <script
       src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID&vault=true">
  </script>

  <div id="paypal-button-container"></div>

  <script>
    paypal.Buttons().render('#paypal-button-container');
  </script>
</body>

Create the subscription

Finally, implement the createSubscription function that's called when the buyer clicks the PayPal button. This function:

  • Calls PayPal using actions.subscription.create() to create a subscription for your plan and includes the plan ID, subscriber details, shipping, and other details.
  • Launches the PayPal subscription window so the buyer can log in and approve the subscription on www.paypal.com.
paypal.Buttons({

  createSubscription: function(data, actions) {

    return actions.subscription.create({

      'plan_id': 'P-2UF78835G6983425GLSM44MA'

    });

  },


  onApprove: function(data, actions) {

    alert('You have successfully created subscription ' + data.subscriptionID);

  }


}).render('#paypal-button-container');

Handle errors and customer drop off using the following handlers:

Use the Subscriptions API

To create a subscription for a plan in active status, call /subscriptions. The buyer must consent to the subscription to activate it.

curl -v -k -X POST https://api.sandbox.paypal.com/v1/billing/subscriptions \
   -H "Accept: application/json" \
   -H "Authorization: Bearer Access-Token" \
   -H "PayPal-Request-Id: SUBSCRIPTION-21092019-001" \
   -H "Prefer: return=representation" \
   -H "Content-Type: application/json" \
   -d '{
      "plan_id": "P-2UF78835G6983425GLSM44MA",
      "start_time": "2019-03-27T06:00:00Z",
      "subscriber": {
        "name": {
          "given_name": "John",
          "surname": "Doe"
        },
        "email_address": "customer@example.com"
      },
      "application_context": {
        "brand_name": "example",
        "locale": "en-US",
        "shipping_preference": "SET_PROVIDED_ADDRESS",
        "user_action": "SUBSCRIBE_NOW",
        "payment_method": {
          "payer_selected": "PAYPAL",
          "payee_preferred": "IMMEDIATE_PAYMENT_REQUIRED"
        },
        "return_url": "https://example.com/returnUrl",
        "cancel_url": "https://example.com/cancelUrl"
      }
    }'
curl -v -k -X POST https://api.sandbox.paypal.com/v1/billing/subscriptions \
  -H "Accept: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -H "PayPal-Request-Id: SUBSCRIPTION-21092019-001" \
  -H "Prefer: return=representation" \
  -H "Content-Type: application/json" \
  -d '{
        "plan_id": "P-4ML8771254154362WXNWU5BC",
        "start_time": "2018-11-01T00:00:00Z",
        "quantity": "20",
        "shipping_amount": {
            "currency_code": "USD",
            "value": "10.00"
        },
        "subscriber": {
          "name": {
              "given_name": "John",
              "surname": "Doe"
          },
          "email_address": "customer@example.com",
          "shipping_address": {
              "name": {
                  "full_name": "John Doe"
              },
              "address": {
                  "address_line_1": "2211 N First Street",
                  "address_line_2": "Building 17",
                  "admin_area_2": "San Jose",
                  "admin_area_1": "CA",
                  "postal_code": "95131",
                  "country_code": "US"
              }
          }
        },
        "application_context": {
          "brand_name": "example",
          "locale": "en-US",
          "shipping_preference": "SET_PROVIDED_ADDRESS",
          "user_action": "SUBSCRIBE_NOW",
          "payment_method": {
              "payer_selected": "PAYPAL",
              "payee_preferred": "IMMEDIATE_PAYMENT_REQUIRED"
          },
          "return_url": "https://example.com/returnUrl",
          "cancel_url": "https://example.com/cancelUrl"
        }
      }'

A successful request returns the HTTP 201 Created status code and a JSON response body that shows subscription details:

{
  "id": "I-KK24TMKLGR0P",
  "plan_id": "P-2UF78835G6983425GLSM44MA",
  "start_time": "2019-03-27T06:00:00Z",
  "subscriber": {
    "name": {
      "given_name": "John",
      "surname": "Doe"
    },
    "email_address": "customer@example.com"
  },
  "create_time": "2019-03-26T07:37:44Z",
  "links": [
    {
      "href": "https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-5G371300PF745064S",
      "rel": "approve",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/subscriptions/I-KK24TMKLGR0P",
      "rel": "edit",
      "method": "PATCH"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/billing/subscriptions/I-KK24TMKLGR0P",
      "rel": "self",
      "method": "GET"
    }
  ],
  "status": "APPROVAL_PENDING",
  "status_update_time": "2019-03-26T07:37:44Z"
}
{
  "id": "I-BW452GLLEP1G",
  "status": "APPROVAL_PENDING",
  "status_update_time": "2018-12-10T21:20:49Z",
  "plan_id": "P-4ML8771254154362WXNWU5BC",
  "start_time": "2018-11-01T00:00:00Z",
  "quantity": "20",
  "shipping_amount": {
      "currency_code": "USD",
      "value": "10.00"
  },
  "subscriber": {
    "name": {
      "given_name": "John",
      "surname": "Doe"
      },
      "email_address": "customer@example.com",
      "shipping_address": {
        "name": {
          "full_name": "John Doe"
          },
          "address": {
            "address_line_1": "2211 N First Street",
            "address_line_2": "Building 17",
            "admin_area_2": "San Jose",
            "admin_area_1": "CA",
            "postal_code": "95131",
            "country_code": "US"
          }
      }
  },
  "create_time": "2018-12-10T21:20:49Z",
  "links": [
    {
      "href": "https://www.paypal.com/webapps/billing/subscriptions?ba_token=BA-2M539689T3856352J",
      "rel": "approve",
      "method": "GET"
    },
    {
      "href": "https://api.paypal.com/v1/billing/subscriptions/I-BW452GLLEP1G",
      "rel": "edit",
      "method": "PATCH"
    },
    {
      "href": "https://api.paypal.com/v1/billing/subscriptions/I-BW452GLLEP1G",
      "rel": "self",
      "method": "GET"
    }
  ]
}

If creating a subscription succeeds, it triggers the BILLING.SUBSCRIPTION.CREATED webhook.

To redirect the buyer to log in to their PayPal account to approve the subscription, use the HATEOAS link from the response.

Example of HATEOAS URL:

GET https://www.paypal.com/webapps/billing/subscriptions?ba_token={BA-Token-ID}

5. Go live

To launch your subcription into production, complete these steps:

Create a PayPal business account

Note: If you already have a PayPal business account, skip to Replace sandbox credentials with live credentials.

  1. Go to the PayPal home page and click Sign Up.
  2. Select Business Account and follow the on-screen instructions.

Replace sandbox credentials with live credentials

  1. Change any API calls from https://api.sandbox.paypal.com to https://api.paypal.com and use your production access token for these calls.

  2. Change the https://www.paypal.com/sdk/js script tag to use your live client ID.

    <script
      src="https://www.paypal.com/sdk/js?client-id=LIVE_CLIENT_ID&vault=true">
    </script>
    

Next

See the full list of features you can add to your integration.