Skip to content
Sign in
An image of the Stripe logo
/
Create account
Sign in
Home
Payments
Finance automation
Banking as a service
Developer tools
No-code
All products
Home
Payments
Finance automation
Home
Payments
Finance automation
Banking as a service
Developer tools
Overview
Get started
About Stripe payments
Start an integration
Payment Links
Checkout
Web Elements
Mobile Elements
Payment scenarios
During the payment
After the payment
Add payment methods
    Overview
    Payment method integration options
    Multiple payment method configurations on dynamic payment methods
    A/B testing on dynamic payment methods
    Payment method targeting on dynamic payment methods
    Register payment method domains
    Bank debits
    Bank redirects
    Bank transfers
    Buy now, pay later
    Credit transfers (Sources)
    Real-time payments
    Regional card installments
    Vouchers
    Wallets
      Alipay
      Apple Pay
      Cash App Pay
      Google Pay
      GrabPay
      PayPal
        Connect your PayPal account
        Accept a payment
        Set up future payments
        Choose settlement preference
        Disputed payments
        Payout reconciliation
        Supported locales
      MobilePay
      Secure Remote Commerce
      WeChat Pay
      Revolut Pay
More payment scenarios
Faster checkout with Link
Other Stripe products
Connect
Terminal
Radar
Financial Connections
Crypto
Identity
Climate
Resources
About the APIs
Implementation guides
Regulation support
Testing
HomePaymentsWalletsPayPal

Set up future PayPal payments

Learn how to save PayPal details and charge your customers later.

Use Stripe Checkout to collect PayPal payment details in advance, with the final amount or payment date determined later. This is useful for:

  • Saving payment methods to a wallet to streamline future purchases.
  • Collecting surcharges after fulfilling a service.
  • Starting a free trial for a subscription.

Enable recurring payments support from Stripe Dashboard

You can request access to the recurring payments directly from the Stripe Dashboard. To do that, go to the Payment Methods Settings page, find PayPal and click Enable next to the Recurring Payments section. You’ll see the pending status. It usually takes up to 5 business days to get access to the recurring payments for PayPal. When access is granted, you’ll see recurring payments on your PayPal settings page.

Use Stripe Checkout to collect PayPal payment details in advance, with the final amount or payment date determined later. This is useful for:

  • Saving payment methods to a wallet to streamline future purchases.
  • Collecting surcharges after fulfilling a service.
  • Starting a free trial for a subscription.

Caution

To start accepting PayPal subscriptions on Stripe, your PayPal account should have Reference Transactions enabled. Please contact your Stripe account manager for more details.

Set up Stripe
Server-side

First, you need a Stripe account. Register now.

Use our official libraries for access to the Stripe API from your application:

Command Line
# Available as a gem sudo gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Create or retrieve a Customer before setup
Server-side

To reuse a PayPal payment method for future payments, it must be attached to a Customer.

You should create a Customer object when your customer creates an account on your business. Associating the ID of the Customer object with your own internal representation of a customer will enable you to retrieve and use the stored payment method details later. If your customer hasn’t created an account, you can still create a Customer object now and associate it with your internal representation of the customer’s account later.

Command Line
curl -X POST https://api.stripe.com/v1/customers \ -u "
sk_test_4eC39HqLyjWDarjtT1zdp7dc
:"

Create a Checkout Session
Client-side
Server-side

Before you can accept PayPal payments, your customer must authorize you to use their PayPal account for future payments through Stripe Checkout.

Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session.

index.html
<html> <head> <title>Checkout</title> </head> <body> <form action="/create-checkout-session" method="POST"> <button type="submit">Checkout</button> </form> </body> </html>

Create a Checkout Session in setup mode to collect the required information. After creating the Checkout Session, redirect your customer to the URL returned in the response.

Command Line
curl https://api.stripe.com/v1/checkout/sessions \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
:
\ -d "payment_method_types[]"="paypal" \ -d mode=setup \ -d customer=
{{CUSTOMER_ID}}
\ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"

When your customer provides their payment method details, they’re redirected to the success_url, a page on your website that informs them that their payment method was saved successfully. Make the Session ID available on your success page by including the {CHECKOUT_SESSION_ID} template variable in the success_url as in the above example.

When your customer clicks on your logo in a Checkout Session without providing their payment method details, Checkout redirects them back to your website by navigating to the cancel_url. This is usually the page on your website that the customer viewed prior to redirecting to Stripe Checkout.

Caution

Don’t rely on the redirect to the success_url alone for detecting payment initiation, as:

  • Malicious users could directly access the success_url without paying and gain access to your goods or services.
  • Customers may not always reach the success_url after a successful payment—they might close their browser tab before the redirect occurs.

Retrieve the payment method
Server-side

After a customer submits their payment details, retrieve the PaymentMethod object. A PaymentMethod stores the customer’s PayPal account information for future payments. You can retrieve the PaymentMethod synchronously using the success_url or asynchronously using webhooks.

The decision to retrieve the PaymentMethod synchronously or asynchronously depends on your tolerance for dropoff, as customers might not always reach the success_url after a successful payment (for example, it’s possible for them to close their browser tab before the redirect occurs). Using webhooks prevents your integration from experiencing this form of dropoff.

Handle checkout.session.completed webhooks, which contain a Session object. To learn more, see setting up webhooks. The following example is a checkout.session.completed response.

{ "id": "evt_1Ep24XHssDVaQm2PpwS19Yt0", "object": "event", "api_version": "2019-03-14", "created": 1561420781, "data": { "object": { "id": "cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k", "object": "checkout.session", "billing_address_collection": null, "cancel_url": "https://example.com/cancel", "client_reference_id": null, "customer": null, "customer_email": null, "display_items": [], "mode": "setup", "setup_intent": "seti_1EzVO3HssDVaQm2PJjXHmLlM", "submit_type": null, "subscription": null, "success_url": "https://example.com/success" } }, "livemode": false, "pending_webhooks": 1, "request": { "id": null, "idempotency_key": null }, "type": "checkout.session.completed" }

Note the value of the setup_intent key, which is the ID for the SetupIntent created with the Checkout Session. A SetupIntent is an object used to set up the customer’s PayPal account information for future payments. Retrieve the SetupIntent object with the ID.

Command Line
curl https://api.stripe.com/v1/setup_intents/seti_1EzVO3HssDVaQm2PJjXHmLlM \ -u "
sk_test_4eC39HqLyjWDarjtT1zdp7dc
:"

Handle post-setup events
Server-side

Use a method such as webhooks to confirm the billing agreement was authorized successfully by your customer, instead of relying on your customer to return to the payment status page. When a customer successfully authorizes the billing agreement, the SetupIntent emits the setup_intent.succeeded webhook event. If a customer doesn’t successfully authorize the billing agreement, the SetupIntent will emit the setup_intent.setup_failed webhook event and returns to a status of requires_payment_method. When a customer revokes the billing agreement from their PayPal account, the mandate.updated is emitted.

Test the integration

Test your PayPal integration with your test API keys by viewing the redirect page. You can test the successful payment case by authenticating the payment on the redirect page. The PaymentIntent will transition from requires_action to succeeded.

To test the case where the user fails to authenticate, use your test API keys and view the redirect page. On the redirect page, click Fail test payment. The PaymentIntent will transition from requires_action to requires_payment_method.

Use the payment method for future payments
Server-side

When you’re ready to charge your customer off-session, use the Customer and PaymentMethod IDs to create a PaymentIntent.

To find a paypal instrument to charge, list the PaymentMethods associated with your Customer.

Command Line
curl -G https://api.stripe.com/v1/payment_methods \ -u "
sk_test_4eC39HqLyjWDarjtT1zdp7dc
:"
\ -d customer={{CUSTOMER_ID}} \ -d type=paypal

When you have the Customer and PaymentMethod IDs, create a PaymentIntent with the amount and currency of the payment. Set a few other parameters to make the off-session payment:

  • Set off_session to true to indicate that the customer is not in your checkout flow during this payment attempt. This causes the PaymentIntent to throw an error if authentication is required.
  • Set the value of the PaymentIntent’s confirm property to true, which causes confirmation to occur immediately when the PaymentIntent is created.
  • Set payment_method to the ID of the PaymentMethod and customer to the ID of the Customer.
Command Line
curl https://api.stripe.com/v1/payment_intents \ -u "
sk_test_4eC39HqLyjWDarjtT1zdp7dc
:"
\ -d amount=1099 \ -d currency=eur \ -d customer={{CUSTOMER_ID}} \ -d "payment_method_types[]"=paypal \ -d payment_method={{PAYMENT_METHOD_ID}} \ -d off_session=true \ -d confirm=true

User-initiated payment method cancellation
Server-side

A customer can cancel the subscription (Billing Agreement) through their PayPal account. When they do so, Stripe emits a mandate.updated webhook. All subsequent Payment Intents using the saved Payment Method will fail until you change to a Payment Method with active mandates. When payments fail for Subscriptions, the status changes to the Subscription status configured in your automatic collection settings. Notify the customer of failure and charge them with a different payment method.

OptionalRemove a saved PayPal account
Server-side

Was this page helpful?
Need help? Contact Support.
Watch our developer tutorials.
Check out our product changelog.
Questions? Contact Sales.
Powered by Markdoc
You can unsubscribe at any time. Read our privacy policy.
On this page
Enable recurring payments support from Stripe Dashboard
Set up Stripe
Create or retrieve a Customer before setup
Create a Checkout Session
Retrieve the payment method
Handle post-setup events
Test the integration
Use the payment method for future payments
User-initiated payment method cancellation
Products Used
Payments
Checkout
Stripe Shell
Test mode
Welcome to the Stripe Shell! Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Log in to your Stripe account and press Control + Backtick (`) on your keyboard to start managing your Stripe resources in test mode. - View supported Stripe commands: - Find webhook events: - Listen for webhook events: - Call Stripe APIs: stripe [api resource] [operation] (e.g., )
The Stripe Shell is best experienced on desktop.
$