Use this file to discover all available pages before exploring further.
After customers save their credit or debit card, they can select it for faster checkout. Customers won’t have to enter payment details for future transactions.Use the JavaScript SDK to save a payer’s card if you aren’t PCI Compliant - SAQ A but want to save credit or debit cards during checkout.
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.
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
You can charge now and save the card in a single flow. Keep your one-time payment session on the client and add a vault directive on your server when creating the order.
Pass document.getElementById("save").checked to your server with the following details in the createOrder() method:
Value of the checkbox
Optional: Card name
Optional: Billing address
No verification
3D Secure
// Initialize the v6 SDK with card-fields componentconst sdk = await window.paypal.createInstance({ clientId: "YOUR_CLIENT_ID", components: ["card-fields"] });// Create a one-time payment session using v6 SDKconst session = sdk.createCardFieldsOneTimePaymentSession();// Check eligibility and render card fieldsif (session.isEligible()) { session.NameField().render("#card-name-field-container"); session.NumberField().render("#card-number-field-container"); session.ExpiryField().render("#card-expiry-field-container"); session.CVVField().render("#card-cvv-field-container");} else { // Handle the workflow when credit and debit cards are not available}// Submit button event handlerconst submitButton = document.getElementById("submit-button");submitButton.addEventListener("click", async () => { try { // Create order - server determines verification settings const saveCheckbox = document.getElementById("save"); const orderResponse = await fetch("/api/paypal/order/create/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ saveCard: saveCheckbox.checked, }), }); const orderData = await orderResponse.json(); const orderId = orderData.id; // Submit the session with billing address const { state, data } = await session.submit(orderId, { billingAddress: { postalCode: "95131" }, }); // Handle successful transaction if (state === "succeeded") { // Capture the order const captureResponse = await fetch(`/api/paypal/orders/${data.orderId}/capture/`, { method: "POST" }); const captureData = await captureResponse.json(); // Handle vault details if card was saved const vault = captureData?.paymentSource?.card?.attributes?.vault; if (vault) { // Save the vault.id and vault.customer.id for future use console.log('Vault ID:', vault.id); console.log('Customer ID:', vault.customer.id); } // Handle successful transaction completion console.log('Payment completed successfully'); } } catch (error) { // Handle any error that may occur console.error('Payment error:', error); }});
To trigger the authentication, pass the required contingency with the verification method in the create orders payload. The verification method can be contingencies parameter with SCA_ALWAYS or SCA_WHEN_REQUIRED.SCA_ALWAYS triggers an authentication for every transaction, while SCA_WHEN_REQUIRED triggers an authentication only when a regional compliance mandate such as PSD2 is required. 3D Secure is supported only in countries with a PSD2 compliance mandate.
// Initialize the v6 SDK with card-fields componentconst sdk = await window.paypal.createInstance({ clientId: "YOUR_CLIENT_ID", components: ["card-fields"] });// Create a one-time payment session using v6 SDKconst session = sdk.createCardFieldsOneTimePaymentSession();// Check eligibility and render card fieldsif (session.isEligible()) { session.NameField().render("#card-name-field-container"); session.NumberField().render("#card-number-field-container"); session.ExpiryField().render("#card-expiry-field-container"); session.CVVField().render("#card-cvv-field-container");} else { // Handle the workflow when credit and debit cards are not available}// Submit button event handlerconst submitButton = document.getElementById("submit-button");submitButton.addEventListener("click", async () => { try { // Create order with 3DS verification directly in client payload const saveCheckbox = document.getElementById("save"); const orderResponse = await fetch("/api/paypal/order/create/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ saveCard: saveCheckbox.checked, // Direct 3DS configuration in client payload card: { attributes: { verification: { method: "SCA_ALWAYS" // or "SCA_WHEN_REQUIRED" }, }, experience_context: { shipping_preference: "NO_SHIPPING", return_url: "https://example.com/returnUrl", cancel_url: "https://example.com/cancelUrl", }, } }), }); const orderData = await orderResponse.json(); const orderId = orderData.id; // Submit the session with billing address const { state, data } = await session.submit(orderId, { billingAddress: { postalCode: "95131" }, }); // Handle successful transaction if (state === "succeeded") { // Capture the order const captureResponse = await fetch(`/api/paypal/orders/${data.orderId}/capture/`, { method: "POST" }); const captureData = await captureResponse.json(); // Handle vault details if card was saved const vault = captureData?.paymentSource?.card?.attributes?.vault; if (vault) { // Save the vault.id and vault.customer.id for future use console.log('Vault ID:', vault.id); console.log('Customer ID:', vault.customer.id); } // Handle successful transaction completion console.log('Payment completed successfully'); } } catch (error) { // Handle any error that may occur console.error('Payment error:', error); }});
Set up your server to call the Orders 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 using the Orders API to add attributes needed to save a card.
Selected the save checkbox. The document.getElementById("save").checked value is true.
To run 3D Secure on the card, set the payment_source.card.attributes.verification.method to SCA_ALWAYS or SCA_WHEN_REQUIRED.SCA_ALWAYS triggers an authentication for every transaction, while SCA_WHEN_REQUIRED triggers an authentication only when a regional compliance mandate such as PSD2 is required. 3D Secure is supported only in countries with a PSD2 compliance mandate.
Note: In the following requests, the payment_source.attributes.vault.store_in_vault with the value ON_SUCCESS means the card is saved with a successful authorization or capture.
Selected the save checkbox. The document.getElementById("save").checked value is true.
Pass the PayPal-generated customer.id as part of this request. Link additional payment_sources to this customer through their customer.id. The customer.id is returned in the response from an authorize or capture request.
Pass the order id to the JavaScript SDK. The SDK updates the order with the new card details. PayPal handles any PCI compliance issues.After the SDK is updated, it triggers the onApprove() method, which receives an object containing the orderID. You can authorize or capture the order when you have the orderID.
Note: The request to save the payment method 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.
In the response from the Authorize or Capture request, the Orders v2 API interacts with the Payment Method Tokens v3 API to save the card.The payment_source.card.attributes.vault stores the card information as the vault.id, which can be used for future payments when the vault.status is VAULTED.
If the payment has been authorized or captured, the payer doesn’t 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:
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.CREATEDwebhook.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:
In this example, the resource.id field is the vault ID, and resource.customer.id is the PayPal-generated customer ID.You can now style your card fields and test a purchase.
Payment processors return the following codes when they receive a transaction request. For advanced card payments, the code displays in the authorization object under the response_code field.The following sample shows the processor response codes returned in an authorization (avs_code) and capture call (cvv_code) response:
Make the server-side list all payment tokens API call to retrieve payment methods saved to a payer’s PayPal-generated customer ID. Based on this list, you can show all saved payment methods to a payer to select during checkout.
Display the saved card to the payer and use the Orders API to make another transaction. Use the vault ID the payer selects as an input to the Orders API.Use supported CSS properties to style the card fields.