To implement recurring billing with PayPal, use the PayPal Subscriptions flow.
This differs from standard MIT recurring (cards, SEPA, etc.): PayPal controls when subscription charges run. You do not call POST /rest/payment again with original_transaction_id for each billing cycle.
Not supported: standard MIT recurring
PayPal does not support merchant-initiated recurring payments using recurring: 1 and original_transaction_id (the card-style flow where you trigger each subsequent charge).
For recurring billing with PayPal, use PayPal Subscriptions only: set recurring: 1, amount: 0, and paypal_plan_id on the initial payment. PayPal triggers future charges; our platform creates child transactions and sends postbacks to your postback_url.
The diagram covers the whole lifecycle: the one-time setup you perform in PayPal, the subscription approval by the customer, the recurring charges PayPal triggers afterwards, and the changes you can apply later.
PayPal Subscriptions — setup, recurring charges, and changes
Scroll horizontally if the diagram is wider than your screen.
i
Merchant
One-time setup, done directly with PayPal before any subscription exists
1
Merchant→PayPal
1. Create Catalogue Product and Plan (PayPal APIs)
10. Postback: setup transaction is registered (amount 0)
11
OneAPI→Payer (Customer)
11. Redirect to success_url or error_url
i
PayPal
PayPal now triggers every billing cycle defined in the plan — you never call the Payment API again
12
PayPal→OneAPI
12. Charges the payer on each billing cycle
13
OneAPI→OneAPI
13. Creates a child transaction for that charge
14
OneAPI→Merchant
14. Postback per charge, with original_transaction_id
i
OneAPI
Charge postbacks go to the postback_url of the setup transaction
15
Merchant→OneAPI
15. Cancel API or Revise API (plan, quantity, shipping)
16
OneAPI→PayPal
16. Cancels or revises the subscription
i
Merchant
Revise can return client_action: redirect when PayPal needs the payer to approve the change
Two points are essential to understand before integrating:
The transaction you create with POST /rest/payment is a setup transaction with amount: 0. It never becomes completed — once the customer approves, it ends in registered.
Every recurring charge is a separate child transaction created by our platform when PayPal reports the billing cycle. Its postback carries original_transaction_id with the setup transaction ID.
When creating a PayPal Subscription through our API, you must already have a PayPal Plan created on PayPal side. Then pass paypal_plan_id when creating the subscription via Payment API.
A subscription produces one setup transaction plus one child transaction per billing cycle. They use different statuses, so treat them separately in your system.
Transaction
Status
Meaning
Setup
pending (2)
The subscription was created in PayPal and is waiting for the customer's approval.
Setup
registered (9)
The customer approved and the subscription is active. This is the final state of the setup transaction — it never becomes completed.
Setup
canceled (5)
The subscription was cancelled through the Cancel API, or PayPal reports it as cancelled or expired.
Charge
completed (3)
A billing cycle was charged successfully.
Charge
declined (6)
A billing cycle failed. The subscription itself stays active until PayPal or you cancel it.
Pass the transaction_id of the setup transaction to Cancel and Revise, not the ID of a charge.
Revise may require a new approval
When the change needs the customer's consent, the Revise API response contains client_action: "redirect" and an action_data.url. Redirect the customer to that URL, otherwise the change is not applied.
Use the same base parameters as in a standard /rest/payment request, with the additions below.
Parameter
Required
Comments
recurring
YES
Must be 1
amount
YES
Must be 0. Future amounts come from the PayPal Plan.
paypal_plan_id
YES
PayPal Plan ID
paypal_subscription_start_time
NO
Subscription start time. If omitted, starts immediately. Must follow RFC 3339 format, e.g. 2021-09-29T11:47:25Z.
paypal_subscription_quantity
NO
Quantity of items in the plan. Only when the plan supports quantities.
Provide first_name, last_name, and email in the billing address for subscription setup. Shipping address parameters are required when the plan is for physical goods.
Any alphanumeric string to identify the Merchant's order
amountFloatrequired
Must be 0. Future billing amounts are defined by the PayPal Plan
currencyStringrequired
3 letter currency code
postback_urlStringrequired
The URL for updates about transaction status are posted
success_urlStringrequired
Where to redirect the user after a successful transaction
error_urlStringrequired
Where to redirect the user after a failed transaction
first_nameStringrequired
Customer's first name (billing address)
last_nameStringrequired
Customer's last name (billing address)
emailStringrequired
Customer's email address
paypal_plan_idStringrequired
PayPal Plan ID created in PayPal (outside our API)
paypal_subscription_start_timeString
Subscription start time in RFC 3339 format, e.g. 2021-09-30T20:47:25Z. Starts immediately when omitted
paypal_subscription_quantityInteger
Quantity within the plan. Only when the plan supports quantities
shipping_costsFloat
Shipping costs when the plan includes shipping
shipping_addressString
Street address. Required with other shipping fields when the plan is for physical goods
shipping_cityString
City of the shipping address
shipping_postal_codeString
Postal code of the shipping address
shipping_stateString
State or region of the shipping address
shipping_countryString
Country code (ISO 3166-1 alpha-2) of the shipping address
shipping_first_nameString
Customer first name for shipping
shipping_last_nameString
Customer last name for shipping
This example creates a PayPal Subscription. See the Create Payment API reference for common and billing address parameters. Include shipping fields when the plan requires physical delivery.
Redirect the customer to the action_data.url. After approval, the customer is redirected to your success_url, and the system starts tracking transactions from this subscription.
For the full list of payment postback fields, see the Payment API. For refund postbacks, see the Refund API. For retry policy and signature verification, see Postbacks.
Every subscription charge is a separate transaction and produces its own postback, sent to the postback_url of the setup transaction. Each one carries the fields below in addition to the standard payment postback fields.
Field
Description
transaction_id
ID of the charge itself. Different on every billing cycle.
original_transaction_id
ID of the subscription setup transaction. Use it to attach the charge to the right subscription.
amount, currency
Amount charged for this cycle. It comes from the PayPal Plan, not from your original request.
paypal_subscription_id
PayPal Subscription ID.
paypal_plan_id
PayPal Plan ID in effect for the charge.
status
completed, declined, or refunded.
Charges are picked up from PayPal notifications and additionally reconciled with PayPal on a daily basis, so a postback for a cycle can arrive with a delay if a notification is lost. Handle postbacks idempotently, keyed on transaction_id.