Save bank details for later use (JavaScript SDK integration)
You can use PayPal’s JavaScript SDK v6 to save Automated Clearing House (ACH) Direct Debit as a payment method for future purchases without an initial transaction, with fully integrated instant bank account verification.
PayPal’s JavaScript SDK provides the necessary pre-built tools to render the Pay with Bank (ACH) button on your webpage and handle payment authorization. Include the JavaScript SDK as a <script> tag in the HTML file that renders your webpage.
The browser-safe token is a client-side access token that authorizes an app to use the JavaScript SDK resources.
A browser-safe token is not the same as a server-side access token. The server-side access token helps PayPal authenticate an app when the app accesses PayPal REST API resources.
To get the browser-safe client token from your server-side code, make a POST call to the /v1/oauth2/token endpoint and include the following:
Encoded app credentials Client ID : Secret in Base64 format, in the Authorization header.
Data parameters:
Parameter
Action
grant_type
Set the parameter value to client_credentials to specify that the app is requesting to exchange client ID and secret for an access token.
response_type
Set the parameter value to client_token to request a client-side access token.
Response: Contains the browser-safe client token in the access_token response parameter.
Copy
// Get OAuth token using client credentialsasync function getClientToken() { try { const response = await fetch("/your-server/api/paypal/browser-safe-client-token"); const data = await response.json(); if (!response.ok) { throw new Error(data.error || "Failed to fetch client token"); } return data.access_token; } catch (error) { console.error("Client token error:", error); throw error; }}
In your client-side code, use the window.paypal.createInstance() method with the following parameters to create a PayPal SDK instance:
Parameter
Action
clientToken
Pass the browser-safe client token.
components
Set to ["bank-ach-payments"] to load and render ACH components.
Response: Contains an SDK instance object with the createBankAchSavePaymentSession() method for creating ACH payment sessions and the findEligibleMethods() method for checking payment method availability.
In your client-side code, use the following methods to determine if you are eligible to offer ACH as a payment method:
findEligibleMethods(): Returns all the eligible payment methods.
isEligible(): Indicates if ACH is an eligible payment method.
Call findEligibleMethods() with an input options object containing the following parameters:
Parameter
Action
currencyCode
Set to the three-letter currency code. Example: USD.
paymentFlow
Set to VAULT_WITHOUT_PAYMENT to vault without an initial payment.
Response: Contains an object with the isEligible() method. Use the method to verify if the eligible payment methods include ACH.
Copy
// Check if ACH is available for vaulting without paymentconst options = { currencyCode: "USD", paymentFlow: "VAULT_WITHOUT_PAYMENT"};// Query for available payment methodsconst paymentMethods = await sdkInstance.findEligibleMethods(options);// Check ACH eligibilityconst isAchEligible = paymentMethods.isEligible("ach");
After confirming eligibility, render the Pay with Bank - ACH button on your webpage:
Define the container for the ACH button: In the HTML file corresponding to the webpage where you want to render the button, include a container element.
Copy
<section class="payment-method-container" id="bank-ach-section"> <h2>Pay with Bank</h2> <!-- BankAchButton web component launches the popup flow --> <bank-ach-button id="paypal-bank-ach-button" hidden></bank-ach-button></section>
Create vault setup token: Call createVaultSetupToken() to get the vault setup token. A vault setup token is a temporary token that is later exchanged for a payment method token.
Create payment session: Use sdkInstance.createBankAchSavePaymentSession() to create a payment session and register the onApprove(), onCancel(), onComplete(), and onError() event handlers.
Attach the onClick event handler and display the button: Use addEventListener() to attach the onClick event handler that triggers the onClick function when customers select the Pay with Bank - ACH button.
Copy
// isAchEligible returns true if ACH payments are eligible for your account.if (isAchEligible) { // Step 2: Create vault setup token const { vaultSetupToken } = await createVaultSetupToken(); // Step 3: Create payment session const bankAchSession = sdkInstance.createBankAchSavePaymentSession({ onApprove, onCancel, onComplete, onError, vaultSetupToken, }); // Step 4: Attach the onClick event handler and display the button const bankButton = document.querySelector("#paypal-bank-ach-button"); bankButton.addEventListener("click", onClick); bankButton.removeAttribute("hidden");} else { console.log("ACH is not eligible");}
The createVaultSetupToken() function creates a vault setup token for saving payment methods without an initial payment.In your client-side code, include the createVaultSetupToken() function that calls the server-side code to create a vault setup token.In your server-side code, include the code to make a POST call to the /v3/vault/setup-tokens endpoint:
Use a Bearer token with full-scope access token in the Authorization header.
Create an onClick event-handler function that starts the authentication flow.In your client-side code, include an event-handler function that is triggered when the user clicks the Pay with Bank - ACH button and starts the authentication (account verification) flow.
Event handlers manage the different outcomes when your customers attempt to save ACH payment methods. In your code, create event-handler functions that handle customer approval, payment cancellation, error scenarios, and completion.
In your client-side code, include the onApprove() event-handler function that receives the vault setup token after the customer successfully verifies their bank account, calls the createPaymentToken() function, and passes the vault setup token.
In your server-side code, include the code to make a POST call to the /v3/vault/payment-tokens endpoint:
Use a valid full-scope Bearer access token and make a POST call to the /v3/vault/payment-tokens endpoint with the vault setup token received from client-side.
Receive the payment token details from the PayPal server and pass them to the client-side code.
In your app code, include the onCancel() event-handler function that handles payment cancellation. Payment cancellation can occur when the customer cancels account verification or the saving process. JavaScript SDK passes the cancellation details to the function’s data parameter.
Copy
function onCancel(data) { console.log("ACH Save Cancelled!", data); console.log("Customer cancelled the bank account linking process");}
In your app code, include the onError(data) event-handler function to process errors that occur during bank account verification or the saving process. JavaScript SDK passes error message and error details to the function’s data parameter.
Copy
function onError(data) { console.log("ACH Save Error:", data); console.error(`Error occurred during bank account linking: ${data.message || 'Unknown error'}`);}
Load your integration page and verify ACH eligibility checking works correctly.
Click the Pay with Bank button to start the bank account authentication process.
Verify the vault setup token is created successfully when the authentication flow begins as documented in the Define createVaultSetupToken function section.
Complete the authentication flow and verify the onApprove callback receives the vault setup token as documented in the Handle approval and create payment token section. When the bank selection popup appears, use the following sandbox test credentials:
Bank selection: Select Demo Bank from the list of available banks.
Confirm your server successfully creates a payment method token using the vault setup token as documented in the Handle approval and create payment token section.