Save PayPal for purchase later with the JavaScript SDK
Last updated: Nov 4th, 9:20am
Save payment methods to charge payers after a set amount of time. For example, you can offer a free trial and charge payers after the trial expires. Payers don't need to be present when charged. No checkout required.
To save PayPal Wallets, payers need to log in to your site, make a purchase, and remain on your site when transactions take place.
Customers with a PayPal Wallet can:
- Review PayPal transactions and transaction history
- Review, add, or remove funding sources
- Review and cancel recurring payments
- Hold a balance in their PayPal account
- Use PayPal to send and receive money
- Withdraw money to a linked bank account
- Use PayPal to transact with merchants
Use cases
Businesses save payment methods if they want customers to:
- Check out without re-entering a payment method
- Pay after use, for example, ride-sharing and food delivery
Know before you code
- To save payment methods, you must be able to identify payers uniquely. For example, payers create an account and log in to your site.
- Complete the steps in Get started to get the following sandbox account information from the Developer Dashboard:
- Your sandbox account login information
- Your access token
- This integration requires a PayPal Developer account.
- This integration must include a server-side call to exchange a setup token for a payment method token.
How it works
PayPal encrypts payment method information and stores it in a digital vault for that customer.
- The payer saves their payment method.
- For a first-time payer, PayPal creates a customer ID. Store this within your system for future use.
- When the customer returns to your website and is ready to check out, pass their PayPal-generated customer ID to the JavaScript SDK. The customer ID tells the JavaScript SDK to save or reuse a saved payment method.
- The payer completes a billing agreement.
- The JavaScript SDK populates the checkout page with each saved payment method. Each payment method appears as a one-click button next to other ways to pay.
The checkout process is now shorter because it uses saved payment information.
Check eligibility
- Go to paypal.com and sign in with your business account.
- Go to Account Settings > Payment Preferences > Save PayPal and Venmo payment methods.
- In the Save PayPal and Venmo payment methods section, select Get Started.
- When you submit profile details, PayPal reviews your eligibility to save PayPal Wallets and Venmo accounts.
- After PayPal reviews your eligibility, you'll see a status of Success, Need more information, or Denied.
Set up account to save payments
Set up your sandbox and live business accounts to save payment methods:
- Log in to the Developer Dashboard.
- Under REST API apps, select your app name.
- Under Sandbox App Settings > App Feature Options, check Accept payments.
- Expand Advanced options. Confirm that Vault is selected.
To go live, you'll need to be vetted to save PayPal Wallets. You can start the vetting process from the Developer Dashboard.
- Only your sandbox business account is enabled to save payment methods. Your developer account remains unaffected.
- You'll complete production onboarding when you're ready to go live.
Generate user ID token for payer
The PayPal OAuth 2.0 API has a response_type
parameter. Set the response_type
to id_token
to retrieve a unique ID token for a payer.
First-time payer
A payer wants to save a payment method for the first time. Modify the POST request to generate id_token
for the payer.
Returning payer
A payer wants to use a saved payment method.
Use the saved PayPal-generated customer ID in the POST body parameter target_customer_id
. The target_customer_id
is a unique ID for a customer generated when the payment_source
is saved to the vault. The target_customer_id
is available when capturing the order or retrieving saved payment information.
Sample server-side user ID token request
- First-time payer
- Returning payer
1curl -s -X POST https://api-m.sandbox.paypal.com/v1/oauth2/token \2 -u CLIENT-ID:CLIENT-SECRET \3 -H "Content-Type: application/x-www-form-urlencoded" \4 -H "PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION" \5 -H "PayPal-Partner-Attribution-Id: BN-CODE" \6 -d "grant_type=client_credentials" \7 -d "response_type=id_token"
Modify the code
Copy the code sample and modify it as follows:
- Change
CLIENT-ID
to your client ID. - Change
CLIENT-SECRET
to your client secret. - Change the customer ID to the PayPal-generated customer ID for a returning payer.
- Change
PAYPAL-AUTH-ASSERTION
to your PayPal-Auth-Assertion token. - Change
BN-CODE
to your PayPal Attribution ID to receive revenue attribution. To find your BN code, see Code and Credential Reference.
A successful request returns fields including an access_token
, id_token
, and the number of seconds the access_token
token is valid.
The id_token
:
- Uniquely identifies each payer.
- Expires in a few minutes because it's meant to be used during checkout. Generate new tokens if the current tokens expire.
Pass user ID token to JavaScript SDK
Pass the id_token
into the JavaScript SDK through the data-user-id-token
.
1<script src="https://www.paypal.com/sdk/js?client-id=CLIENT-ID&merchant-id=MERCHANT-ID" data-user-id-token="ID-TOKEN"></script>
Modify the code
Copy the code sample and modify it as follows:
- Change
CLIENT-ID
to your client ID. - Change
MERCHANT-ID
to your merchant ID. - Change
ID-TOKEN
to theid_token
from the previous step.
Create setup token
You request a setup token from your server. Pass the setup token from your server to the SDK with the createVaultSetupToken
callback.
The createVaultSetupToken
callback:
- Calls the server endpoint you created to generate and retrieve the setup token.
- Makes a request to your server endpoint.
Then, your server uses its access token to create and return the setup token to the client.
Any errors that occur while creating a setup token show up in the onError
callback provided to the card fields component.
Supported callback
Callback | Returns | Description |
---|---|---|
createVaultSetupToken |
Setup token (string) | The merchant's server must receive this callback. Create a setup token for cards from the merchant server. The SDK then saves the payment method and updates the setup token with payment method details. |
Client-side code sample
- Platform
- Merchant
1window.paypal.Buttons({2 createVaultSetupToken: async () => {3 // The merchant calls their server API to generate a setup token4 // and return it here as a string5 const result = await fetch("example.com/create/setup/token", {6 method: "POST",7 })8 return result.token9 }10})
Modify the code
- Change
ACCESS-TOKEN
to your sandbox app's access token. - Change
REQUEST-ID
to a set of unique alphanumeric characters such as a time stamp. - Set the
usage_type
underpayment_source.paypal
toMERCHANT
. - In the
createVaultSetupToken
, call the endpoint on your server to create a setup token with the Payment Method Tokens API.createVaultSetupToken
returns the setup token as a string.
Server-side code sample
Set up your server to call the Payment Method Tokens API. The button that the payer selects determines the payment_source
sent in the following sample.
This SDK uses the Payment Method Tokens API to save payment methods in the background. Use the following request to add attributes needed to save a PayPal Wallet:
- Sample platform API request
- Sample merchant API request
- Sample platform API response
- Sample merchant API response
1curl -v -k -X POST https://api-m.sandbox.paypal.com/v3/vault/setup-tokens \2 -H "Content-Type: application/json" \3 -H "Authorization: Bearer ACCESS-TOKEN" \4 -H "PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION" \5 -H "PayPal-Partner-Attribution-Id: BN-CODE" \6 -H "PayPal-Request-Id: REQUEST-ID" \7 -d '{8 "payment_source": {9 "paypal": {10 "usage_type": "PLATFORM",11 "experience_context": {12 "return_url": "https://example.com/returnUrl",13 "cancel_url": "https://example.com/cancelUrl"14 }15 }16 }17 }'
Modify the code
- Change
ACCESS-TOKEN
to your sandbox app's access token. - Change
PAYPAL-AUTH-ASSERTION
to your PayPal-Auth-Assertion token. - Change
BN-CODE
to your PayPal Attribution ID to receive revenue attribution. To find your BN code, see Code and Credential Reference. - Change
REQUEST-ID
to a set of unique alphanumeric characters such as a time stamp. - In the
createVaultSetupToken
, call the endpoint on your server to create a setup token with the Payment Method Tokens API.createVaultSetupToken
returns the setup token as a string.
Response
Return the id
to your client to call for the payer approval flow if the payment_source
needs payer approval.
Payer approval
If payer approval is required, the client SDK calls the payer approval flow. The approval flow takes the payer through PayPal Checkout.
Create payment token
You can store a Merchant Customer ID aligned with your system to simplify the mapping of customer information within your system and PayPal when creating a payment token. This is an optional field that will return the value shared in the response.
Use an approved setup token to save the payer's payment method to the vault. Then, copy the sample request code to generate a payment token:
Supported callback
Callback | Returns | Description |
---|---|---|
onApprove |
{ vaultSetupToken: string } |
The merchant gets the updated vaultSetupToken when the payment method is saved. The merchant must store the vaultSetupToken token in their system. |
Client-side sample request
Modify the following request to match your server endpoint and payload:
1window.paypal.Buttons({2 onApprove: ({ vaultSetupToken }) => {3 // Send the vaultSetupToken to the merchant server4 // for the merchant server to generate a payment token5 return fetch("example.com/create/payment/token", { body: JSON.stringify({ vaultSetupToken }) })6 },7})
Sample API request and response
- Sample platform API request
- Sample merchant API request
- Sample API response
1curl -v -k -X POST https://api-m.sandbox.paypal.com/v3/vault/payment-tokens \2 -H "Content-Type: application/json" \3 -H "Authorization: Bearer ACCESS-TOKEN" \4 -H "PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION" \5 -H "PayPal-Partner-Attribution-Id: BN-CODE" \6 -H "PayPal-Request-Id: REQUEST-ID" \7 -d '{8 "payment_source": {9 "token": {10 "id": "4G4976650J0948357",11 "type": "SETUP_TOKEN"12 }13 }14 }'
Modify the code
Copy the code sample and modify it as follows:
- Change
ACCESS-TOKEN
to your sandbox access token. - Change
PAYPAL-AUTH-ASSERTION
to your PayPal-Auth-Assertion token. - Change
BN-CODE
to your PayPal Attribution ID to receive revenue attribution. To find your BN code, see Code and Credential Reference. - Change
REQUEST-ID
to a unique alphanumeric set of characters such as a time stamp. - Use the token as the payment source and complete the rest of the source object for your use case and business.
- Use your setup token ID to pass in the payment source parameter and type as the
SETUP_TOKEN
.
Step result
A successful request results in the following:
- An HTTP response code of
200
or201
. Returns200
for an idempotent request. - ID of the payment token and associated payment method information.
- HATEOAS links:
Rel | Method | Description |
---|---|---|
delete |
DELETE |
Make a DELETE request to delete the payment token. |
self |
GET |
Make a GET request to this link to retrieve data about the saved payment method. |
Integrate back end
The following sample shows a complete back-end integration to save PayPal for purchase later:
1import "dotenv/config";2import express from "express";3const { PORT = 8888 } = process.env;4const app = express();5app.set("view engine", "ejs");6app.use(express.static("public"));7// Create setup token8app.post("/create/setup/token", async (req, res) => {9 try {10 // Use your access token to securely generate a setup token11 // with an empty payment_source12 const vaultResponse = await fetch("https://api-m.sandbox.paypal.com/v3/vault/setup-tokens", {13 method: "POST",14 body: JSON.stringify({ payment_source: { paypal: { usage_type: "MERCHANT" } } }),15 headers: {16 "Authorization": "Bearer ${ACCESS-TOKEN}",17 "PayPal-Request-Id": Date.now(),18 "PayPal-Auth-Assertion":"PAYPAL-AUTH-ASSERTION",19 "PayPal-Partner-Attribution-Id":"BN-CODE",20 }21 })22 // Return the reponse to the client23 res.json(vaultResponse);24 } catch (err) {25 res.status(500).send(err.message);26 }27})28// Create payment token from a setup token29app.post("/create/payment/token/:setupToken", async (req, res) => {30 const { setupToken } = req.params;31 try {32 const paymentTokenResult = await fetch(33 "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens",34 {35 method: "POST",36 body: {37 payment_source: {38 token: {39 id: setupToken,40 type: "SETUP_TOKEN"41 }42 }43 },44 headers: {45 "Authorization": "Bearer ${ACCESS-TOKEN}",46 "PayPal-Request-Id": Date.now(),47 "PayPal-Auth-Assertion":"PAYPAL-AUTH-ASSERTION",48 "PayPal-Partner-Attribution-Id":"BN-CODE",49 }50 })51 const paymentMethodToken = paymentTokenResult.id52 const customerId = paymentTokenResult.customer.id53 await save(paymentMethodToken, customerId)54 res.json(captureData);55 } catch (err) {56 res.status(500).send(err.message);57 }58})59const save = async function(paymentMethodToken, customerId) {60 // Specify where to save the payment method token61}62app.listen(PORT, () => {63 console.log('Server listening at http://localhost:${PORT}/');64})
Integrate front end
The following sample shows how a full script to save PayPal might appear in HTML:
1<div id="paypal-buttons-container"></div>2<script src="https://www.paypal.com/sdk/js?client-id=CLIENT-ID&merchant-id=MERCHANT-ID" data-user-id-token="ID-TOKEN"></script>3<script>4 window.paypal.Buttons({5 createVaultSetupToken: async () => {6 // The merchant calls their server API to generate a setup token7 // and return it here as a string8 const result = await fetch("example.com/create/setup/token", {9 method: "POST",10 })11 return result.token12 },13 onApprove: async ({ vaultSetupToken }) => {14 return fetch("example.com/create/payment/token", { body: JSON.stringify({ vaultSetupToken }) })15 },16 onError: (error) => {17 console.log("An error occurred: ", error)18 }19 }).render("#paypal-buttons-container");20</script>
Test your integration
- Render a PayPal Button with callbacks defined.
- Select the button and complete the pop-up flow to approve saving the PayPal Wallet.
- On your server, save the
vaultSetupToken
and the PayPal-generatedcustomer.id
. Associate these tokens with the designated payer. - Make a call on your server to swap your setup token for a payment token from the Payment Method Tokens API.
- Save or use an existing
customer.id
depending on whether the payer is a first-time payer or returning payer:- For a first-time payer, save the PayPal-generated
customer.id
. Thecustomer.id
identifies the payer and their saved payment methods. - For a returning payer, use the PayPal-generated
customer.id
to swap thesetup-token
for apayment-token
.
- For a first-time payer, save the PayPal-generated
- Save the
payment-token
for future use.
Optional: Show saved payment methods
We recommend creating a page on your site where payers can see their saved payment methods as in the following example: