Help Article

How do I use Express Checkout with Recurring Payments?

With PayPal Express Checkout, you may use Recurring Payments as part of most standard Business accounts.

Note: Recurring Payments has been disabled in the code for China and Germany.

The following examples will show API requests and responses for the calls your API caller would make, as well as use cases for each way to use this.

 
Use Case 1
You want to sign someone up for a service, but:
  • You have an initial sign-up fee that is greater than the recurring amount.
  • You need to collect the sign-up fee before the user uses the service, but the sign-up fee includes the initial month's payment.

The customer chooses the service they want on your site and is sent to the checkout page, where you display the Express Checkout button and make the API call for the SetExpressCheckout Method:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=SetExpressCheckout
VERSION=64.0
RETURNURL=https://www.mysite.com/return.php
CANCELURL=https://localhost
PAYMENTACTION=Authorization
AMT=100.00
CURRENCYCODE=USD
DESC=test EC payment
L_BILLINGTYPE0=RecurringPayments
L_BILLINGAGREEMENTDESCRIPTION0=SameEveryTime

The preceding call tells PayPal to set up a payment authorization for 100.00 and then use this token later for a Recurring Payment Profile.

Note: The "L_BILLINGAGREEMENTDESCRIPTION0" value must be the same in every processing call. If it changes, the call will fail. You should receive the API response for the above call:
 
Array
(
[TOKEN] => EC%2d3EG521428H665543W
[TIMESTAMP] => 2011%2d03%2d04T20%3a52%3a38Z
[CORRELATIONID] => 685d0ef158ba6
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
)

Check the ACK for any errors, then use the Token in your redirect URL: https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-3EG521428H665543W

The user will then be redirected to the PayPal site, where they log in and review the information. When they click Agree and Continue, they're returned to the RETURNURL as specified in the SetExpressCheckout API Request. The Token and PayerID are posted to you: https://www.mysite.com/return.php?token=EC-3EG521428H665543W&PayerID=5X4X6FQUMKFVA

You then grab the token to do the GetExpressCheckoutDetails API call: 
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=GetExpressCheckoutDetails
VERSION=64.0
TOKEN=EC-3EG521428H665543W
Then you receive the response:
 
Array
(
[TOKEN] => EC%2d3EG521428H665543W
[PHONENUM] => 408%2d983%2d5678
[BILLINGAGREEMENTACCEPTEDSTATUS] => 1
[CHECKOUTSTATUS] => PaymentActionNotInitiated
[TIMESTAMP] => 2011%2d03%2d04T20%3a55%3a40Z
[CORRELATIONID] => eb3dcd77ff87
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
[EMAIL] => email%40domain%2ecom
[PAYERID] => 5X4X6FQUMKFVA
[PAYERSTATUS] => verified
[BUSINESS] => Nate%27s%20Test%20Store
[FIRSTNAME] => Nate
[LASTNAME] => Tester
[COUNTRYCODE] => US
[SHIPTONAME] => Nate%27s%20Test%20Store
[SHIPTOSTREET] => 1%20Main%20St
[SHIPTOCITY] => San%20Jose
[SHIPTOSTATE] => CA
[SHIPTOZIP] => 95131
[SHIPTOCOUNTRYCODE] => US
[SHIPTOCOUNTRYNAME] => United%20States
[ADDRESSSTATUS] => Confirmed
[CURRENCYCODE] => USD
[AMT] => 100%2e00
[SHIPPINGAMT] => 0%2e00
[HANDLINGAMT] => 0%2e00
[TAXAMT] => 0%2e00
[DESC] => test%20EC%20payment
[INSURANCEAMT] => 0%2e00
[SHIPDISCAMT] => 0%2e00
[PAYMENTREQUEST_0_CURRENCYCODE] => USD
[PAYMENTREQUEST_0_AMT] => 0%2e01
[PAYMENTREQUEST_0_SHIPPINGAMT] => 0%2e00
[PAYMENTREQUEST_0_HANDLINGAMT] => 0%2e00
[PAYMENTREQUEST_0_TAXAMT] => 0%2e00
[PAYMENTREQUEST_0_DESC] => test%20EC%20payment
[PAYMENTREQUEST_0_INSURANCEAMT] => 0%2e00
[PAYMENTREQUEST_0_SHIPDISCAMT] => 0%2e00
[PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED] => false
[PAYMENTREQUEST_0_SHIPTONAME] => Nate%27s%20Test%20Store
[PAYMENTREQUEST_0_SHIPTOSTREET] => 1%20Main%20St
[PAYMENTREQUEST_0_SHIPTOCITY] => San%20Jose
[PAYMENTREQUEST_0_SHIPTOSTATE] => CA
[PAYMENTREQUEST_0_SHIPTOZIP] => 95131
[PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE] => US
[PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME] => United%20States
[PAYMENTREQUESTINFO_0_ERRORCODE] => 0
)
You then use the variables in the GetExpressCheckoutDetails API response to display the information to the user on your own Review page. This is where you tell the buyer something like, "You will now be charged 100.00 dollars, and your next payment is due on MM/DD/YYYY. This will be automatically deducted from your account at that time."

Next, lay out the above variables in a readable receipt-type format. As you're performing an authorization right from the original order, you'll perform a DoExpressCheckoutPayment API call:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=DoExpressCheckoutPayment
VERSION=64.0
TOKEN=EC-3EG521428H665543W
PAYMENTACTION=Authorization
PAYERID=5X4X6FQUMKFVA
AMT=100.00
CURRENCYCODE=USD
L_BILLINGTYPE0=RecurringPayments
L_BILLINGAGREEMENTDESCRIPTION0=SameEveryTime

Note: In this example, the L_BILLINGAGREEMENTDESCRIPTION0=SameEveryTime name value pair is still being passed.

You now receive the API Response for the DoExpressCheckout Payment API call:
 
Array
(
[TOKEN] => EC%2d3EG521428H665543W
[SUCCESSPAGEREDIRECTREQUESTED] => false
[TIMESTAMP] => 2011%2d03%2d04T20%3a58%3a20Z
[CORRELATIONID] => 8a37685f613c3
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
[TRANSACTIONID] => 2SE97607J4552160J
[TRANSACTIONTYPE] => expresscheckout
[PAYMENTTYPE] => instant
[ORDERTIME] => 2011%2d03%2d04T20%3a58%3a19Z
[AMT] => 100%2e00
[TAXAMT] => 0%2e00
[CURRENCYCODE] => USD
[PAYMENTSTATUS] => Pending
[PENDINGREASON] => authorization
[REASONCODE] => None
[PROTECTIONELIGIBILITY] => Eligible
[INSURANCEOPTIONSELECTED] => false
[SHIPPINGOPTIONISDEFAULT] => false
[PAYMENTINFO_0_TRANSACTIONID] => 2SE97607J4552160J
[PAYMENTINFO_0_TRANSACTIONTYPE] => expresscheckout
[PAYMENTINFO_0_PAYMENTTYPE] => instant
[PAYMENTINFO_0_ORDERTIME] => 2011%2d03%2d04T20%3a58%3a19Z
[PAYMENTINFO_0_AMT] => 0%2e01
[PAYMENTINFO_0_TAXAMT] => 0%2e00
[PAYMENTINFO_0_CURRENCYCODE] => USD
[PAYMENTINFO_0_PAYMENTSTATUS] => Pending
[PAYMENTINFO_0_PENDINGREASON] => authorization
[PAYMENTINFO_0_REASONCODE] => None
[PAYMENTINFO_0_PROTECTIONELIGIBILITY] => Eligible
[PAYMENTINFO_0_ERRORCODE] => 0
[PAYMENTINFO_0_ACK] => Success
)

At this point, there is no Recurring Profile, but the authorization for 100.00 has been completed.

Next, you need to create the profile:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=CreateRecurringPaymentsProfile
VERSION=64.0
TOKEN=EC-3EG521428H665543W
SUBSCRIBERNAME=Mr.Subscriber
PROFILESTARTDATE=2011-03-11T00:00:00Z
DESC=SameEveryTime
MAXFAILEDPAYMENTS=3
AUTOBILLAMT=AddToNextBilling
BILLINGPERIOD=Week
BILLINGFREQUENCY=1
AMT=0.01
FIRSTNAME=John
LASTNAME=Doe
STREET=1 Anything Street
CITY=Topeka
STATE=KS
COUNTRYCODE=US
ZIP=66601
CURRENCYCODE=USD

Note: The DESC is set to the same value as the L_BILLINGAGREEMENTDESCRIPTION0 variable in the previous calls. This is the correct way to do this.

You then receive the response:
 
Array
(
[PROFILEID] => I%2d0X2SRN9N57T7
[PROFILESTATUS] => ActiveProfile
[TIMESTAMP] => 2011%2d03%2d04T21%3a00%3a36Z
[CORRELATIONID] => e76a78bbe8b7
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
)

Your Profile is now set up and will start on the PROFILESTARTDATE as set in the CreateRecurringPaymentsProfile API call.

 

Use Case 2

You want the profile to start today, and bill today, but there are no additional fees and the initial amount will always be the same amount. The user selects the service they want, and then you make a SetExpressCheckout API call:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=SetExpressCheckout
VERSION=64.0
RETURNURL=https://www.mysite.com/return.php
CANCELURL=https://localhost
PAYMENTACTION=Sale
AMT=0.01
CURRENCYCODE=USD
DESC=test EC payment
L_BILLINGTYPE0=RecurringPayments
L_BILLINGAGREEMENTDESCRIPTION0=SameEveryTime

You receive the SetExpressCheckout API response:
 
Array
(
[TOKEN] => EC%2d59153533VJ078841F
[TIMESTAMP] => 2011%2d03%2d04T21%3a02%3a28Z
[CORRELATIONID] => 3dc5ad74251d6
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
)

Redirect to PayPal.com:

https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-59153533VJ078841F

The customer logs in to PayPal.com and clicks Agree and Continue. They're then returned to your site as set in the RETURNURL variable in the SetExpressCheckout API call.

You're then posted the Token and PayerID:

https://www.mysite.com/return.php?token=EC-59153533VJ078841F&PayerID=5X4X6FQUMKFVA

You then use the Token to make the GetExpressCheckoutDetails API call:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=GetExpressCheckoutDetails
VERSION=64.0
TOKEN=EC-59153533VJ078841F

You receive the API response from the GetExpressCheckoutDetails API call:
 
Array
(
[TOKEN] => EC%2d59153533VJ078841F
[PHONENUM] => 408%2d983%2d5678
[BILLINGAGREEMENTACCEPTEDSTATUS] => 1
[CHECKOUTSTATUS] => PaymentActionNotInitiated
[TIMESTAMP] => 2011%2d03%2d04T21%3a04%3a50Z
[CORRELATIONID] => 49b48bb4174e3
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
[EMAIL] => email%40domain%2ecom
[PAYERID] => 5X4X6FQUMKFVA
[PAYERSTATUS] => verified
[BUSINESS] => Nate%27s%20Test%20Store
[FIRSTNAME] => Nate
[LASTNAME] => Tester
[COUNTRYCODE] => US
[SHIPTONAME] => Nate%27s%20Test%20Store
[SHIPTOSTREET] => 1%20Main%20St
[SHIPTOCITY] => San%20Jose
[SHIPTOSTATE] => CA
[SHIPTOZIP] => 95131
[SHIPTOCOUNTRYCODE] => US
[SHIPTOCOUNTRYNAME] => United%20States
[ADDRESSSTATUS] => Confirmed
[CURRENCYCODE] => USD
[AMT] => 0%2e01
[SHIPPINGAMT] => 0%2e00
[HANDLINGAMT] => 0%2e00
[TAXAMT] => 0%2e00
[DESC] => test%20EC%20payment
[INSURANCEAMT] => 0%2e00
[SHIPDISCAMT] => 0%2e00
[PAYMENTREQUEST_0_CURRENCYCODE] => USD
[PAYMENTREQUEST_0_AMT] => 0%2e01
[PAYMENTREQUEST_0_SHIPPINGAMT] => 0%2e00
[PAYMENTREQUEST_0_HANDLINGAMT] => 0%2e00
[PAYMENTREQUEST_0_TAXAMT] => 0%2e00
[PAYMENTREQUEST_0_DESC] => test%20EC%20payment
[PAYMENTREQUEST_0_INSURANCEAMT] => 0%2e00
[PAYMENTREQUEST_0_SHIPDISCAMT] => 0%2e00
[PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED] => false
[PAYMENTREQUEST_0_SHIPTONAME] => Nate%27s%20Test%20Store
[PAYMENTREQUEST_0_SHIPTOSTREET] => 1%20Main%20St
[PAYMENTREQUEST_0_SHIPTOCITY] => San%20Jose
[PAYMENTREQUEST_0_SHIPTOSTATE] => CA
[PAYMENTREQUEST_0_SHIPTOZIP] => 95131
[PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE] => US
[PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME] => United%20States
[PAYMENTREQUESTINFO_0_ERRORCODE] => 0
)

You then use those variables to display the information to the user, along with the terms of your next payment and any additional information you want to display before they commit to the profile creation.

When the user clicks Confirm, you then create the profile:
 
USER=apiuser_api1.paypal.com
PWD=J833MXXXXXXXPTCY
SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31AnhJm2kyJdqZJj09FSV0IW0QIvoR
METHOD=CreateRecurringPaymentsProfile
VERSION=64.0
TOKEN=EC-59153533VJ078841F
SUBSCRIBERNAME=Mr.Subscriber
PROFILESTARTDATE=2011-03-11T00:00:00Z
DESC=SameEveryTime
MAXFAILEDPAYMENTS=3
AUTOBILLAMT=AddToNextBilling
BILLINGPERIOD=Week
BILLINGFREQUENCY=1
AMT=0.01
FIRSTNAME=John
LASTNAME=Doe
STREET=1 Anything Street
CITY=Topeka
STATE=KS
COUNTRYCODE=US
ZIP=66601
CURRENCYCODE=USD

You receive the profile information via the response:
 
Array
(
[PROFILEID] => I%2dYSR915D3KBLG
[PROFILESTATUS] => ActiveProfile
[TIMESTAMP] => 2011%2d03%2d04T21%3a06%3a26Z
[CORRELATIONID] => da8144ffdfdbf
[ACK] => Success
[VERSION] => 64%2e0
[BUILD] => 1741654
)

The profile has been created and will start on the PROFILESTARTDATE value as set in the CreateRecurringPaymentProfile API call.

See the PayPal Developer Portal for the most up-to-date content on Recurring Payments API calls.
We’re sorry. The page you’re looking for is no longer available. To search again or contact us, please visit our Help Centre.