Get Started
This guide walks you through a complete Unified Checkout integration: enabling the service, generating a session on your server, loading the client-side SDK, and rendering a checkout on your page.
Enable Unified Checkout
Before you integrate, confirm that your merchant ID (MID) is configured to use Unified Checkout and that the payment methods you intend to offer are set up.
Log In to the
Log in to the using your test or production credentials:
Open the Unified Checkout Configuration
In the left navigation panel, choose Payment Configuration > Unified Checkout. The Unified Checkout customer experience page appears.
Configure Your Checkout Experience
The customer experience page is organized into three configuration screens:
- Payment Options: enable, add, remove, and arrange the payment methods that Unified Checkout displays to your customers.
- Look & Feel: configure the visual appearance and branding of the payment UI.
- Customer Information and Payment Flow: control which billing and shipping data Unified Checkout collects and which follow-on services process the payment.
Generate a Session on Your Server
Your server authenticates your merchant credentials with a server-to-server call to the Sessions API. The response is a signed JSON Web Token (JWT) known as the capture context. The capture context tells the client-side JavaScript library how to behave: which payment methods to show, which card networks to accept, and how to style the payment UI.
Call the Sessions API
Send a POST request to the sessions resource. This example shows the minimum required fields: targetOrigins, locale, country, and the order amount and currency:
curl -X POST /uc/v1/sessions \ -H "Content-Type: application/json" \ -d '{ "targetOrigins": ["https://merchant.example.com"], "locale": "en_US", "country": "US", "data": { "orderInformation": { "amountDetails": { "totalAmount": "21.00", "currency": "USD" } } } }'curl -X POST /uc/v1/sessions \ -H "Content-Type: application/json" \ -d '{ "targetOrigins": ["https://merchant.example.com"], "locale": "en_US", "country": "US", "data": { "orderInformation": { "amountDetails": { "totalAmount": "21.00", "currency": "USD" } } } }'The targetOrigins array must include every origin that hosts the SDK.
Handle the Response
The response body contains the capture context: a JWT that includes a transaction-specific public key for end-to-end encryption and the merchant configuration that drives the client-side experience.
Pass the Capture Context to the Browser
Store the capture context on your server, and pass it to the customer's browser as the session JWT that the client-side library uses to initialize.
Load the Client-Side SDK
Load the Unified Checkout JavaScript library using the exact URL your server received in the capture context response — do not hardcode a version number in your integration. The capture context includes a clientLibrary field with the versioned asset URL for that session, and a clientLibraryIntegrity field with a Subresource Integrity value for it. Your server extracts these values from the capture context JWT and renders them into the script tag it serves to the browser:
<script src="{{clientLibrary}}" integrity="{{clientLibraryIntegrity}}" crossorigin="anonymous"></script>Because the server resolves clientLibrary for every session, your integration always loads a version of the SDK that is compatible with that session, even as the server-side feature set changes. See Versioning for how the server selects this version.
Initialize the SDK and Create a Checkout
Initialize the SDK
Call VAS.UnifiedCheckout() with the capture context JWT from your server. It returns a Promise that resolves to a client instance:
const client = await VAS.UnifiedCheckout(sessionJWT);Initialization validates the JWT signature and checks that the current page origin matches targetOrigins. If the JWT is invalid or expired, initialization throws a UnifiedCheckoutError.
Create a Checkout
Create a checkout to render the list of available payment methods and handle the payment flow:
const checkout = await client.createCheckout();Mount the Checkout
Call mount() to attach the payment UI to your page:
// Sidebar mode — payment screen appears as an overlayconst result = await checkout.mount('#payment-buttons');// Embedded mode — button list and payment screen both render inlineconst result = await checkout.mount({ paymentSelection: '#payment-buttons', paymentScreen: '#payment-form'});When the session includes a completeMandate, autoProcessing defaults to true, and mount() resolves with the completed payment result once the customer finishes the payment flow:
const client = await VAS.UnifiedCheckout(sessionJWT);const checkout = await client.createCheckout();const result = await checkout.mount('#payment-buttons');// result is the completed payment result JWTWhen you set autoProcessing to false, mount() resolves with a transient token instead, and you call checkout.complete() to finish the payment:
const client = await VAS.UnifiedCheckout(sessionJWT);const checkout = await client.createCheckout({ autoProcessing: false });const transientToken = await checkout.mount('#payment-buttons');// Complete the payment when your server is readyconst result = await checkout.complete(transientToken);Listen for Events and Handle Completion
Subscribe to checkout-level and client-level events to track the payment lifecycle:
checkout.on('ready', (data) => { console.log('Available methods:', data.availablePaymentMethods);});checkout.on('paymentMethodSelected', (data) => { console.log('Selected:', data.type);});client.on('error', (err) => { console.error(`[${err.source}] ${err.code}: ${err.message}`);});Send the value that mount() resolves with (the completed payment result or the transient token, depending on autoProcessing) to your server so your server can verify it and, if needed, authorize the payment.
For the complete event and error reference, see Events and Error Handling.
Clean Up
Remove the payment UI and release SDK resources when the payment flow completes or the customer navigates away.
Unmount the payment UI without destroying the checkout when you need to hide it temporarily:
checkout.unmount();// Mount again laterconst result = await checkout.mount('#payment-buttons');Destroy the checkout and the client when you are finished with the integration:
checkout.destroy();client.destroy();checkout.unmount() is reversible. checkout.destroy() and client.destroy() are permanent: call them at the end of the payment flow, or the SDK iframes remain in the page.
Next Steps
- Test Your Setup: validate your integration with test cards and error scenarios.
- Integration Patterns: compare the Checkout, Button, Trigger, and Components integration patterns.
- Troubleshooting: resolve common session, mount, and origin errors.
- Sessions: full server-side session configuration reference.
Thanks for your feedback!
Last published: September 29, 2026