On this page
No Headings
Last updated: June 18, 2026
After customers save their PayPal Wallet, they can select it for faster checkout. Customers won't have to enter payment details for future transactions.
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:
Important: Don't save PayPal as a payment method during purchase. For more information about securely saving payment methods and optimizing the buyer experience, see our Best practices guide.
Get up and running in GitHub Codespaces
GitHub Codespaces are cloud-based development environments where you can code and test your PayPal integrations. Learn more
PayPal encrypts payment method information and stores it in a digital vault for that customer.
The checkout process is now shorter because it uses saved payment information.
The following is an example of what a payer sees after they save their PayPal Wallet on your site. Returning payers can select their saved payment method at checkout to pay faster.
The payer uses a credit card in their PayPal Wallet in the following example:

Businesses save payment methods if they want customers to:
Set up your sandbox and live business accounts to save payment methods:
To go live, you'll need to be vetted for PayPal Wallet. You can start the vetting process from the Merchant Servicing Dashboard.
Tip: When prompted for data such as a phone number for the sandbox business request, enter any number that fits the required format. Since this is a sandbox request, the data doesn't have to be factual.
The OAuth 2.0 API to retrieve an access_token has an additional parameter, response_type, that can be set to id_token. Include the id_token and access_token in the response.
A payer wants to save a payment method for the first time. Modify the following code to generate a user ID token for the payer:
curl -s -X POST "https://api-m.sandbox.paypal.com/v1/oauth2/token"\
-u CLIENT_ID:CLIENT_SECRET \
-H "Content-Type: application/x-www-form-urlencoded"\
-d "grant_type=client_credentials"\
-d "response_type=id_token"CLIENT_ID to your client ID.CLIENT_SECRET to your client secret.{
"access_token" : "A21AAJ--LVQmYlaxd_TDFOqVs4C3Xa7kPfa0Es7O35_9TEWaWRCMw7-NBJuBWqXZhb3eOolNnMtxwhoMP3NqHOJm1rvPDehfQ",
"app_id" : "APP-80W284485P519543T",
"expires_in" : 32400,
"id_token" : "eyJraWQiOiJjMmVjMmZiYjIzMGU0ZDkzOTNhMGFmZjEzZTY4MjFjMSIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwczovL2FwaS5zYW5kYm94LnBheXBhbC5jb20iLCJzdWIiOiJQQ0haQ1RMMjVSNllXIiwiYWNyIjpbImNsaWVudCJdLCJzY29wZSI6WyJCcmFpbnRyZWU6VmF1bHQiXSwib3B0aW9ucyI6eyJjdXN0b21lcl9pZCI6IjIxMzM3NTk5MiJ9LCJheiI6ImdjcC5zbGMiLCJleHRlcm5hbF9pZCI6WyJQYXlQYWw6UENIWkNUTDI1UjZZVyIsIkJyYWludHJlZTo2ZDNtY3pqN2h3cHE4Y2cyIl0sImV4cCI6MTY2NDIzOTA1MCwiaWF0IjoxNjY0MjM4MTUwLCJqdGkiOiJVMkFBSVNTRkozbVlJUE8wdGYwTF93NFVmTHpfeGFCNHhYRndkTnRibTNXOVhtQ2xoU2NuWGZtMmRxbjU5QjY2akRVbzNhd1Y0ODlsbFpZOVBuV2RFTVN4ZlpZVDZKTS1mUi1rdEotcV9pdkZKMHlCWXdpdU1HaldPR2psZWktUSJ9.PSDUMcZxsEEUlKNqKHgFhrmAcKeCeJMIMhzMrVV5PpTftlB_Xmgzwl1Fir0H0OYSjmopcVPNfXyXl55jxaqJdQ",
"nonce" : "2022-09-27T00:22:30ZxsLQJVSYoAx7jqj1JJgr3onjVSPVL5juzZbId-Z-bwQ",
"scope" : "https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/vault/payment-tokens/read https://uri.paypal.com/services/disputes/read-buyer https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller https://uri.paypal.com/services/paypalhere openid https://uri.paypal.com/services/payments/payment/authcapture https://uri.paypal.com/services/disputes/read-seller Braintree:Vault https://uri.paypal.com/services/payments/refund https://uri.paypal.com/services/identity/activities https://api-m.sandbox.paypal.com/v1/vault/credit-card https://api-m.sandbox.paypal.com/v1/payments/.* https://uri.paypal.com/services/reporting/search/read https://uri.paypal.com/payments/payouts https://uri.paypal.com/services/vault/payment-tokens/readwrite https://api-m.sandbox.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/shipping/trackers/readwrite https://uri.paypal.com/services/subscriptions https://uri.paypal.com/services/applications/webhooks https://api-m.sandbox.paypal.com/v1/payments/refund https://api-m.sandbox.paypal.com/v1/payments/sale/.*/refund",
"token_type" : "Bearer"
}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:
Tip: Each buyer session is unique. Set up your server to generate a new client token each time payment fields render on your page.
Pass the id_token from your server into the JavaScript SDK using the data-user-id-token.
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID" data-user-id-token="YOUR-ID-TOKEN"></script>Include client-side callbacks to:
<script>
paypal.Buttons({
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/yourserver.com/createOrder', {
method: 'post',
body: JSON.stringify({
source: data.paymentSource, //paypal / venmo / etc.
}),
// Here for product info
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
// Authorize or capture the transaction after payer approves
onApprove: (data, actions) => {
return fetch('/yourserver.com/order/' + data.orderID + '/capture/', {
method: 'post'
});
},
onCancel(data, actions) {
console.log(`Order Canceled - ID: ${data.orderID}`);
},
onError(err) {
console.error(err);
}
}).render('#paypal-button-container');
</script>Set up your server to call the Create Order API. The button that the payer selects determines the payment_source sent in the following sample.
This SDK uses the Orders v2 API to save payment methods in the background. Use the following request to add attributes needed to save a PayPal Wallet.
In the following request, the payment_source.paypal.attributes.vault.store_in_vault with the value ON_SUCCESS means the PayPal button is saved with a successful authorization or capture.
Pass the payment_source.paypal.experience_context and include the return_url and cancel_url to redirect the payer after they approve or cancel the order.
Create an order with PayPal as a payment source and store the PayPal Wallet in vault:
curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS-TOKEN" \
-H "PayPal-Request-Id: REQUEST-ID" \
-d '{
"intent": "CAPTURE",
"purchase_units": [{
"amount": {
"currency_code": "USD",
"value": "100.00"
}
}],
"payment_source": {
"paypal": {
"attributes": {
"vault": {
"store_in_vault": "ON_SUCCESS",
"usage_type": "MERCHANT",
"customer_type": "CONSUMER"
}
},
}
}
}'Return the id to your client to call the payer approval flow if the payment_source needs payer approval.
Note: The request to save the PayPal button is made when the order is created through payment_source.attributes.vault.store_in_vault. Vault details are available only after an order is authorized or captured.
{
"id": "5O190127TN364715T",
"status": "PAYER_ACTION_REQUIRED",
"payment_source": {
"paypal": {}
},
"links": [{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.paypal.com/checkoutnow?token=5O190127TN364715T",
"rel": "payer-action",
"method": "GET"
}
]
}If payer approval is required, the client SDK calls the payer approval flow. The approval flow takes the payer through PayPal Checkout.
curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T/capture \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS-TOKEN" \
-d '{}'The HTTP response codes HTTP 2xx or HTTP 200 are returned for a successful request.
The capture is successful if the purchase_units[0].payments.captures.status is COMPLETED. You can confirm with the payer that the payment has been captured.
In the response from the authorize or capture request, the Orders v2 API interacts with the Payment Method Tokens v3 API. The Payment Method Tokens v3 API allows a PayPal Wallet to be saved. The response from the Orders v2 API contains the:
vault.idcustomer.idvault.statuslinks for the payment token of a recently saved PayPal Wallet.{
"id": "5O190127TN364715T",
"status": "COMPLETED",
"payment_source": {
"paypal": {
"attribute": {
"vault": {
"id": "3nqvjt3n",
"customer": {
"id": "208743798"
},
"status": "VAULTED",
"links": [{
"href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/3nqvjt3n",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/3nqvjt3n",
"rel": "delete",
"method": "DELETE"
},
{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "up",
"method": "GET"
}
]
}
},
"name": {
"given_name": "Firstname",
"surname": "Lastname"
},
"email_address": "[email protected]",
"phone_number": {
"national_number": "2025212022"
},
"account_id": "QYR5Z8XDVJNXQ",
"address": {
"country_code": "US"
},
}
},
"payer": {
"name": {
"given_name": "Firstname",
"surname": "Lastname"
},
"email_address": "[email protected]",
"phone_number": {
"national_number": "2025212022"
},
"payer_id": "QYR5Z8XDVJNXQ",
"address": {
"country_code": "US"
}
}
"purchase_units": [{
"reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
"payments": {
"captures": [{
"id": "3C679366HH908993F",
"status": "COMPLETED",
"amount": {
"currency_code": "USD",
"value": "100.00"
},
"seller_protection": {
"status": "ELIGIBLE",
"dispute_categories": [
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]
},
"final_capture": true,
"seller_receivable_breakdown": {
"gross_amount": {
"currency_code": "USD",
"value": "100.00"
},
"paypal_fee": {
"currency_code": "USD",
"value": "3.00"
},
"net_amount": {
"currency_code": "USD",
"value": "97.00"
}
},
"create_time": "2022-01-01T21:20:49Z",
"update_time": "2022-01-01T21:20:49Z",
"links": [{
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/3C679366HH908993F",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/3C679366HH908993F/refund",
"rel": "refund",
"method": "POST"
}
]
}]
}
}],
"links": [{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "self",
"method": "GET"
}]
}If the payment has been authorized or captured, the payer does not need to be present to save a payment_source. To keep checkout times as short as possible, the Orders API responds as soon as payment is captured.
If the attributes.vault.status returned after payment is APPROVED, you won't have a vault.id yet. An example of the attributes object from this scenario is in the following sample:
"attributes": {
"vault": {
"status": "APPROVED",
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "up",
"method": "GET"
}
]
}
}The Payment Method Tokens API still saves the payment source even after the Orders API returns its response and sends a webhook after the payment source is saved.
In order to retrieve a vault_id when an APPROVED status is returned, you'll need to subscribe to the VAULT.PAYMENT-TOKEN.CREATED webhook.
The Payment Method Tokens API sends a webhook after the payment source is saved. An example of the VAULT.PAYMENT-TOKEN.CREATED webhook payload is shown in the following sample:
{
"id": "WH-72S4353495632143A-68K769747M133873M",
"event_version": "1.0",
"create_time": "2022-08-27T01:25:57.462Z",
"resource_type": "payment_token",
"resource_version": "3.0",
"event_type": "VAULT.PAYMENT-TOKEN.CREATED",
"summary": "A payment token has been created.",
"resource": {
"time_created": "2022-08-26T18:25:57.449PDT",
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7vrxmrw",
"rel": "self",
"method": "GET",
"encType": "application/json"
},
{
"href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7vrxmrw",
"rel": "delete",
"method": "DELETE",
"encType": "application/json"
}
],
"id": "3nqvjt3n",
"payment_source": {
"paypal": {
"permit_multiple_payment_tokens": false,
"usage_type": "MERCHANT",
"customer_type": "CONSUMER",
"email_address": "[email protected]",
"payer_id": "VTR4JYK7STE7J"
}
},
"customer": {
"id": "208743798"
}
},
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-72S4353495632143A-68K769747M133873M",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-72S4353495632143A-68K769747M133873M/resend",
"rel": "resend",
"method": "POST"
}
]
}In the previous example, the resource.id field is the vault ID. The resource.customer.id is the PayPal-generated customer ID.
Run the following tests in the PayPal sandbox to ensure you can save PayPal Wallets.
See a sample Save Payment Method integration in the PayPal GitHub repository.
api-m.sandbox.paypal.com to api-m.paypal.com when going live with your integration.payment_source.paypal.attributes.vault for subsequent or recurring transactions.