On this page
No Headings
Last updated: July 9, 2026
After customers save their Venmo account, they can select it for faster checkout. Customers won't have to enter payment details for future transactions.
Venmo is available in the US only.
This integration requires a PayPal Developer account.
Note: The API URLs shown in the following examples point to a live environment. Venmo is not fully supported in the sandbox environment. For more information, refer to the Venmo testing guidelines.
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 Venmo account on your site. Returning payers can select their saved payment method at checkout to pay faster.
Businesses save payment methods if they want customers to:
Enable Venmo vaulting in your Developer Dashboard for production.
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.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.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:
payment_source is saved to the vaultNote: Use the customer identifier generated by PayPal and not the identifier that you use to identify the customer in your system.
curl -s -X POST "https://api-m.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"\
-d "target_customer_id=PayPal-generated customer id"CLIENT_ID to your client ID.CLIENT_SECRET to your client secret.PayPal-generated customer ID with the actual one that was stored in your system.{
"access_token" : "A21AALfqL90lNr8kExf9CI8cQIP19XkpBfdyFf3nPdTc0XbXCNXdrrK92QaywEZ2jqNIyumP_fezAwMOibDaOWqGONVfyob5g",
"app_id" : "APP-80W284485P519543T",
"expires_in" : 32400,
"id_token" : "eyJraWQiOiJjMmVjMmZiYjIzMGU0ZDkzOTNhMGFmZjEzZTY4MjFjMSIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwczovL2FwaS5zYW5kYm94LnBheXBhbC5jb20iLCJzdWIiOiJQQ0haQ1RMMjVSNllXIiwiYWNyIjpbImNsaWVudCJdLCJzY29wZSI6WyJCcmFpbnRyZWU6VmF1bHQiXSwib3B0aW9ucyI6eyJjdXN0b21lcl9pZCI6IjIxMzM3NTk5MiJ9LCJheiI6ImdjcC5zbGMiLCJleHRlcm5hbF9pZCI6WyJQYXlQYWw6UENIWkNUTDI1UjZZVyIsIkJyYWludHJlZTo2ZDNtY3pqN2h3cHE4Y2cyIl0sImV4cCI6MTY2NDIzODEwMiwiaWF0IjoxNjY0MjM3MjAyLCJqdGkiOiJVMkFBSkVBN21DaWtTSGlfd3c2OVM5ZW92Vmo0UXZGanVNZzZYLUlZN1VqNDh4Z3NIaEhEVUZoelRFSG1vRGdvSXczcnFieTFFSEpubDFmb19SNFF3SVhPTlVPbHQ0dmZVQ0RxdklrRUdmWFdqeGNnYUNfTWVnam1KNk1IVTdVUSJ9.iMDYOU8RA6lv0U06LHcOSmpdEX6fVP4Y3-NLExZ28hUpBNDtCQ9NXxmYhjjAiYAbdtpVaYQjpig1NawbuAHNug",
"nonce" : "2022-09-27T00:06:42ZtVVASdHDZEsuDY56mMQp6wlR5rOknNY1LqrC1oOVVmI",
"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.paypal.com/v1/vault/credit-card https://api-m.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.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.paypal.com/v1/payments/refund https://api-m.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.
Use the data-user-id-token to pass the id_token from your server to the PayPal JavaScript SDK.
<!-- Set up a container element for the button -->
<div id="venmo-button-container"></div>
<!-- Include the PayPal JavaScript SDK. Replace 'YOUR_CLIENT_ID' with your client ID.-->
<!-- Pass 'enable-funding=venmo' as a query parameter. -->
<!-- Replace 'YOUR_ID_TOKEN' with the id_token from your server. -->
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&enable-funding=venmo" data-user-id-token="YOUR_ID_TOKEN"></script>
<script>
// Render the Venmo button into the #paypal-button-container
paypal.Buttons().render('#venmo-button-container')
</script>Create an order on the client and server side.
The following JavaScript functions are incompatible with Pay with Venmo when saving payment methods to the vault:
onShippingAddressChangeonShippingChangeonShippingOptionsChangeInclude 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'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
// Authorize or capture the transaction after the payer approves
onApprove: (data, actions) => {
return actions.order.capture().then(function(orderData) {
//Authorize or Capture API
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. To save Venmo as a payment method, use payment_source.venmo.attributes with the value ON_SUCCESS to pass appropriate attributes.
Create an order with Venmo as a payment source:
curl -v -X POST https://api-m.paypal.com/v2/checkout/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
"intent": "CAPTURE",
"purchase_units": [{
"amount": {
"currency_code": "USD",
"value": "100.00"
}
}],
"payment_source": {
"venmo": {
"email_address": "[email protected]",
"experience_context": {
"shipping_preference": "SET_PROVIDED_ADDRESS",
"brand_name": "EXAMPLE INC"
},
"attributes": {
"vault": {
"store_in_vault": "ON_SUCCESS",
"usage_type": "MERCHANT"
}
}
}
}
}Check the status of the response. Return the id to your client to call the payer approval flow if the payment_source needs payer approval.
The payer is redirected to the payer_action URL.
{
"id": "5O190127TN364715T",
"status": "PAYER_ACTION_REQUIRED",
"payment_source": {
"venmo": {
"email_address": "[email protected]"
}
},
"links": [{
"href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "self",
"method": "GET"
}]
}The SDK prompts the payer to switch to Venmo. In Venmo, the payer agrees to save their account as a payment method.
If the payer doesn't have Venmo installed or uses a desktop, the SDK presents the payer with a QR code. The payer scans the code with a mobile device camera or the Venmo in-app scanning feature.
After the payer approves, the onApprove function is called in the JavaScript SDK. Depending on the intent passed, the server calls the following APIs:
intent passed was CAPTUREintent passed was AUTHORIZE as part of your Create Order call.If authorization or capture is successful, a vault.id is also created.
curl -v -X POST https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T/authorize \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{}'curl -v -X POST https://api-m.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 Venmo account to be saved. The response from the Orders v2 API contains the:
vault.idcustomer.idvault.statuslinks for the payment token of a recently saved Venmo account.On a successful response, the payment_source.venmo.attribute.vault.status is set to VAULTED along with the vault ID at payment_source.venmo.attribute.vault.id.
Capture order response:
{
"id": "5O190127TN364715T",
"status": "COMPLETED",
"payment_source": {
"venmo": {
"user_name": "nickname",
"name": {
"given_name": "Firstname",
"surname": "Lastname"
},
"email_address": "[email protected]",
"phone_number": {
"national_number": "2025212022"
},
"account_id": "QYR5Z8XDVJNXQ",
"address": {
"address_line_1": "123 Townsend St",
"address_line_2": "Floor 6",
"admin_area_2": "San Francisco",
"admin_area_1": "CA",
"postal_code": "94107",
"country_code": "US"
},
"attribute": {
"vault": {
"id": "ckfmsf",
"customer": {
"id": "4029352050"
},
"status": "VAULTED",
"links": [{
"href": "https://api-m.paypal.com/v3/vault/payment-tokens/ckfmsf",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.paypal.com/v3/vault/payment-tokens/ckfmsf",
"rel": "delete",
"method": "DELETE"
},
{
"href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "up",
"method": "GET"
}
]
}
}
}
},
"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,
"disbursement_mode": "INSTANT",
"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.paypal.com/v2/payments/captures/3C679366HH908993F",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.paypal.com/v2/payments/captures/3C679366HH908993F/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "up",
"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.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-54U753518P812093G-3GD69489S94654234",
"event_version": "1.0",
"create_time": "2022-10-13T23:04:17.378Z",
"resource_type": "payment_token",
"resource_version": "3.0",
"event_type": "VAULT.PAYMENT-TOKEN.CREATED",
"summary": "A payment token has been created.",
"resource": {
"create_time": "2018-12-11T21:21:49.000Z",
"update_time": "2018-12-11T21:21:49.000Z",
"id": "ckfmsf",
"customer": {
"id": "4029352050"
},
"payment_source": {
"venmo": {
"description": "Description for Venmo to be shown to Venmo payer",
"shipping": {
"name": {
"full_name": "Firstname Lastname"
},
"address": {
"address_line_1": "2211 N First Street",
"address_line_2": "Building 17",
"admin_area_2": "San Jose",
"admin_area_1": "CA",
"postal_code": "95131",
"country_code": "US"
}
},
"usage_pattern": "IMMEDIATE",
"usage_type": "MERCHANT",
"customer_type": "CONSUMER",
"email_address": "[email protected]",
"payer_id": "VYYFH3WJ4JPJQ",
"user_name": "firstnamelastname"
}
},
"links": [
{
"rel": "self",
"href": "https://api-m.paypal.com/v3/vault/payment-tokens/ckfmsf",
"method": "GET"
},
{
"rel": "delete",
"href": "https://api-m.paypal.com/v3/vault/payment-tokens/ckfmsf",
"method": "DELETE"
}
]
},
"links": [
{
"href": "https://api-m.paypal.com/v1/notifications/webhooks-events/WH-54U753518P812093G-3GD69489S94654234",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.paypal.com/v1/notifications/webhooks-events/WH-54U753518P812093G-3GD69489S94654234/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 your live environment to ensure you can save Venmo as a payment method:
payment_source.venmo.attributes.vault for subsequent or recurring transactions.