Subscriptions Integration

DocsLegacyLast updated: September 10th 2021, @ 10:26:36 am


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:

1curl -v -X POST https://api-m.sandbox.paypal.com/v1/catalogs/products
2 -H "Content-Type: application/json"
3 -H "Authorization: Bearer <Access-Token>"
4 -H "PayPal-Request-Id: <merchant-generated-ID>" // Optional and if passed, helps identify idempotent requests
5-d '{
6 "name": "Video Streaming Service",
7 "description": "Video streaming service",
8 "type": "SERVICE",
9 "category": "SOFTWARE",
10 "image_url": "https://example.com/streaming.jpg",
11 "home_url": "https://example.com/home"
12}'

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

1{
2 "id": "PROD-XYAB12ABSB7868434",
3 "name": "Video Streaming Service",
4 "description": "Video streaming service",
5 "type": "SERVICE",
6 "category": "SOFTWARE",
7 "image_url": "https://example.com/streaming.jpg",
8 "home_url": "https://example.com/home",
9 "create_time": "2020-01-10T21:20:49Z",
10 "update_time": "2020-01-10T21:20:49Z",
11 "links": [
12 {
13 "href": "https://api-m.sandbox.paypal.com/v1/catalogs/products/72255d4849af8ed6e0df1173",
14 "rel": "self",
15 "method": "GET"
16 },
17 {
18 "href": "https://api-m.sandbox.paypal.com/v1/catalogs/products/72255d4849af8ed6e0df1173",
19 "rel": "edit",
20 "method": "PATCH"
21 }
22 ]
23}

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. But there is no limit to the number of plans you could create for different types of services.

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.

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1curl -v -k -X POST https://api-m.sandbox.paypal.com/v1/billing/plans
2-H "Accept: application/json"
3-H "Authorization: Bearer Access-Token"
4-H "PayPal-Request-Id: PLAN-18062020-001" // merchant generated ID, optional and needed for idempotent samples
5-H "Prefer: return=representation"
6-H "Content-Type: application/json"
7-d '{
8 product_id: 'PROD-6XB24663H4094933M',
9name: 'Basic Plan',
10description: 'Basic plan',
11billing_cycles: [
12 {
13 frequency: {
14 interval_unit: 'MONTH',
15 interval_count: 1,
16 },
17 tenure_type: 'TRIAL',
18 sequence: 1,
19 total_cycles: 1,
20 },
21 {
22 frequency: {
23 interval_unit: 'MONTH',
24 interval_count: 1,
25 },
26 tenure_type: 'REGULAR',
27 sequence: 2,
28 total_cycles: 12,
29 pricing_scheme: {
30 fixed_price: {
31 value: '10',
32 currency_code: 'USD',
33 },
34 },
35 },
36],
37payment_preferences: {
38 auto_bill_outstanding: true,
39 setup_fee: {
40 value: '10',
41 currency_code: 'USD',
42 },
43 setup_fee_failure_action: 'CONTINUE',
44 payment_failure_threshold: 3,
45},
46taxes: {
47 percentage: '10',
48 inclusive: false,
49},
50 }'

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

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1{
2 id: 'P-2UF78835G6983425GLSM44MA',
3 product_id: 'PROD-6XB24663H4094933M',
4 name: 'Basic Plan',
5 status: 'ACTIVE',
6 description: 'Basic plan',
7 billing_cycles: [
8 {
9 frequency: {
10 interval_unit: 'MONTH',
11 interval_count: 1,
12 },
13 tenure_type: 'TRIAL',
14 sequence: 1,
15 total_cycles: 1,
16 },
17 {
18 pricing_scheme: {
19 fixed_price: {
20 currency_code: 'USD',
21 value: '10.00',
22 },
23 },
24 frequency: {
25 interval_unit: 'MONTH',
26 interval_count: 1,
27 },
28 tenure_type: 'REGULAR',
29 sequence: 2,
30 total_cycles: 12,
31 },
32 ],
33 payment_preferences: {
34 auto_bill_outstanding: true,
35 setup_fee: {
36 currency_code: 'USD',
37 value: '10.00',
38 },
39 setup_fee_failure_action: 'CONTINUE',
40 payment_failure_threshold: 3,
41 },
42 taxes: {
43 percentage: '10.00',
44 inclusive: false,
45 },
46 quantity_supported: false,
47 create_time: '2020-02-26T07:01:04Z',
48 update_time: '2020-02-26T07:01:04Z',
49 links: [
50 {
51 href:
52 'https://api-m.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA',
53 rel: 'self',
54 method: 'GET',
55 },
56 {
57 href:
58 'https://api-m.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA',
59 rel: 'edit',
60 method: 'PATCH',
61 },
62 {
63 href:
64 'https://api-m.sandbox.paypal.com/v1/billing/plans/P-2UF78835G6983425GLSM44MA/deactivate',
65 rel: 'self',
66 method: 'POST',
67 },
68 ],
69}

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

4. Create a subscription

Start a subscription in one of two ways:

  • Smart Payment Buttons in the JavaScript SDK - 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.
  • Subscriptions REST API - Use the Subscriptions REST API to fully customize the subscriber experience on your site.

Note: (UK merchants) Credit is a regulated activity in the UK. Before integrating a PayPal Credit button, you must be authorized to act as a credit broker and have a credit agreement with PayPal. For more information, speak to your Customer Success Manager (CSM) or contact business customer support

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.

1<!DOCTYPE html>
2<head>
3 <meta name="viewport" content="width=device-width, initial-scale=1">
4 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
5</head>
6<body>
7 <script
8 src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID&vault=true&intent=subscription">
9 </script>
10</body>

Make sure you:

  • Add the <!DOCTYPE html> tag for optimal browser 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

OptionExample valueDefaultDescription
client-idtestrequiredYour 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=test as a shortcut.
vaulttrue, falsefalseSet to true for subscriptions.
intentcapture, authorize, subscription, tokenizecaptureSet to subscription for subscriptions.

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

Availability: The JavaScript SDK onShippingChange function is not compatible with Subscriptions.

Render the Smart Payment Button

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

1<body>
2 <script
3 src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID&vault=true&intent=subscription">
4 </script>
5 <div id="paypal-button-container"></div>
6 <script>
7 paypal.Buttons().render('#paypal-button-container');
8 </script>
9</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.
1paypal.Buttons({
2 createSubscription: function(data, actions) {
3 return actions.subscription.create({
4 'plan_id': 'P-2UF78835G6983425GLSM44MA'
5 });
6 },
7 onApprove: function(data, actions) {
8 alert('You have successfully created subscription ' + data.subscriptionID);
9 }
10}).render('#paypal-button-container');

Handle errors and customer drop off using the following handlers:

Use the Subscriptions API

With the Subscriptions API, buyers can create subscriptions either through logging in to their PayPal account or by providing credit or debit card information.

PayPal subscriber flow

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

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1curl -v -k -X POST https://api-m.sandbox.paypal.com/v1/billing/subscriptions
2 -H "Accept: application/json"
3 -H "Authorization: Bearer Access-Token"
4 -H "PayPal-Request-Id: SUBSCRIPTION-21092020-001"
5 -H "Prefer: return=representation"
6 -H "Content-Type: application/json"
7 -d '{
8 plan_id: 'P-2UF78835G6983425GLSM44MA',
9 start_time: '2020-02-27T06:00:00Z',
10 subscriber: {
11 name: {
12 given_name: 'John',
13 surname: 'Doe',
14 },
15 email_address: 'customer@example.com',
16 },
17 application_context: {
18 brand_name: 'example',
19 locale: 'en-US',
20 shipping_preference: 'SET_PROVIDED_ADDRESS',
21 user_action: 'SUBSCRIBE_NOW',
22 payment_method: {
23 payer_selected: 'PAYPAL',
24 payee_preferred: 'IMMEDIATE_PAYMENT_REQUIRED',
25 },
26 return_url: 'https://example.com/returnUrl',
27 cancel_url: 'https://example.com/cancelUrl',
28 },
29}'

A successful request returns the HTTP 201 Created status code and a JSON response body that returns a unique subscription ID and subscription details.

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1{
2 id: 'I-KK24TMKLGR0P',
3 plan_id: 'P-2UF78835G6983425GLSM44MA',
4 start_time: '2020-02-27T06:00:00Z',
5 subscriber: {
6 name: {
7 given_name: 'John',
8 surname: 'Doe',
9 },
10 email_address: 'customer@example.com',
11 },
12 create_time: '2020-02-26T07:37:44Z',
13 links: [
14 {
15 href:
16 'https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-5G371300PF745064S',
17 rel: 'approve',
18 method: 'GET',
19 },
20 {
21 href:
22 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-KK24TMKLGR0P',
23 rel: 'edit',
24 method: 'PATCH',
25 },
26 {
27 href:
28 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-KK24TMKLGR0P',
29 rel: 'self',
30 method: 'GET',
31 },
32 ],
33 status: 'APPROVAL_PENDING',
34 status_update_time: '2020-02-26T07:37:44Z',
35}

If creating a subscription succeeds, it triggers the BILLING.SUBSCRIPTION.CREATED webhook. When a subscription has been paid using auto debit, it triggers the PAYMENT.SALE.COMPLETED 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}

Direct card flow

With the direct card flow, the buyer enters the card details on the merchant's page and subscribes. You then call /subscriptions to create the subscription.

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1curl -v -k -X POST https://api-m.sandbox.paypal.com/v1/billing/subscriptions
2 -H "Accept: application/json"
3 -H "Authorization: Bearer Access-Token"
4 -H "PayPal-Request-Id: SUBSCRIPTION-21092019-001"
5 -H "Prefer: return=representation"
6 -H "Content-Type: application/json"
7 -d '
8 {
9 plan_id: 'P-2UF78835G6983425GLSM44MA',
10 start_time: '2020-01-01T00:00:00Z',
11 shipping_amount: {
12 currency_code: 'USD',
13 value: '10.00',
14 },
15 subscriber: {
16 name: {
17 given_name: 'John',
18 surname: 'Doe',
19 },
20 email_address: 'customer@example.com',
21 shipping_address: {
22 name: {
23 full_name: 'John Doe',
24 },
25 address: {
26 address_line_1: '2211 N First Street',
27 address_line_2: 'Building 17',
28 admin_area_2: 'San Jose',
29 admin_area_1: 'CA',
30 postal_code: '95131',
31 country_code: 'US',
32 },
33 },
34 payment_source: {
35 card: {
36 number: '4111111111111111',
37 expiry: '2020-02',
38 security_code: '121',
39 name: 'John Doe',
40 billing_address: {
41 address_line_1: '2211 N First Street',
42 address_line_2: '17.3.160',
43 admin_area_1: 'CA',
44 admin_area_2: 'San Jose',
45 postal_code: '95131',
46 country_code: 'US',
47 },
48 },
49 },
50 },
51}'

A successful request returns the HTTP 201 Created status code and a JSON response body that returns a unique subscription ID and subscription details.

  1. Fixed Pricing Plan
  2. User-Seat Pricing Plan
1{
2 status: 'ACTIVE',
3 status_update_time: '2020-03-22T10:43:33Z',
4 id: 'I-EXCCE2B4J0D5',
5 plan_id: 'P-2UF78835G6983425GLSM44MA',
6 start_time: '2020-05-01T00:00:00Z',
7 quantity: '1',
8 shipping_amount: {
9 currency_code: 'USD',
10 value: '10.0',
11 },
12 subscriber: {
13 name: {
14 given_name: 'John',
15 surname: 'Doe',
16 },
17 email_address: 'customer@example.com',
18 shipping_address: {
19 name: {
20 full_name: 'John Doe',
21 },
22 address: {
23 address_line_1: '2211 N First Street',
24 address_line_2: 'Building 17',
25 admin_area_2: 'San Jose',
26 admin_area_1: 'CA',
27 postal_code: '95131',
28 country_code: 'US',
29 },
30 },
31 payment_source: {
32 card: {
33 last_digits: '4781',
34 name: 'John Doe',
35 billing_address: {
36 address_line_1: '2211 N First Street',
37 address_line_2: '17.3.160',
38 admin_area_2: 'San Jose',
39 admin_area_1: 'CA',
40 postal_code: '95131',
41 country_code: 'US',
42 },
43 },
44 },
45 },
46 create_time: '2020-03-22T10:43:33Z',
47 links: [
48 {
49 href:
50 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-EXCCE2B4J0D5/cancel',
51 rel: 'cancel',
52 method: 'POST',
53 },
54 {
55 href:
56 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-EXCCE2B4J0D5',
57 rel: 'edit',
58 method: 'PATCH',
59 },
60 {
61 href:
62 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-EXCCE2B4J0D5',
63 rel: 'self',
64 method: 'GET',
65 },
66 {
67 href:
68 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-EXCCE2B4J0D5/suspend',
69 rel: 'suspend',
70 method: 'POST',
71 },
72 {
73 href:
74 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-EXCCE2B4J0D5/capture',
75 rel: 'capture',
76 method: 'POST',
77 },
78 ],
79}

If creating a subscription succeeds, it triggers the BILLING.SUBSCRIPTION.ACTIVATED webhook. When a subscription has been paid using auto debit, it triggers the PAYMENT.SALE.COMPLETED webhook.

5. Go live

To launch your subscription 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-m.sandbox.paypal.com to https://api-m.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.
1<script
2 src="https://www.paypal.com/sdk/js?client-id=LIVE_CLIENT_ID&vault=true">
3</script>

Next