Migrating to v1
The v1 SDK simplifies integration with fewer lines of code, a streamlined API, and features like auto-processing and a full event system. Most migrations involve straightforward method renames — the core flow remains the same.
Summary of Changes
This table summarizes the key differences between the pre-v1 (v0) SDK and the v1 SDK:
| Aspect | v0 | v1 |
|---|---|---|
| Initialization | new Accept(session).unifiedPayments() | VAS.UnifiedCheckout(session) |
| Display the payment UI | up.show(options) | checkout.mount(target) |
| Complete a transaction | up.complete(token) (manual only) | checkout.complete(token) or automatic using autoProcessing |
| Events | None | Full event system on client and checkout |
| Cleanup | up.hide() + up.dispose() | checkout.unmount() (reversible) + checkout.destroy() (permanent) |
| Session creation endpoint | /up/v1/capture-contexts | /uc/v1/sessions |
consumerAuthentication field | Boolean | Enum: 3DS, NONE, PASSKEY |
Initialization
const accept = new Accept(sessionJWT);const up = accept.unifiedPayments();const client = await VAS.UnifiedCheckout(sessionJWT);These are the key differences:
- v1 is a single async factory call (no intermediate
Acceptobject) - v1 validates the JSON Web Token (JWT) signature and target origins during initialization
Session Creation Endpoint
The server-side endpoint your integration calls to create a session changes in v1. Update your server-side code to call the new endpoint:
| v0 endpoint | v1 endpoint |
|---|---|
/up/v1/capture-contexts | /uc/v1/sessions |
The response from the v1 endpoint continues to include the clientLibrary URL and clientVersion value described in Versioning.
Consumer Authentication
In v0, the consumerAuthentication field in the session request is a boolean. In v1, consumerAuthentication is an enum with an expanded set of options:
| Value | Description |
|---|---|
3DS | Use 3-D Secure authentication. |
NONE | Do not perform consumer authentication. |
PASSKEY | Use passkey-based authentication. |
Update any code that sets or checks consumerAuthentication as a boolean to use one of the enum values instead.
Displaying Payment UI
// Sidebarconst token = await up.show({ containers: { paymentSelection: '#buttons' }});// Embeddedconst token = await up.show({ containers: { paymentSelection: '#buttons', paymentScreen: '#form' }});// Create the checkout before mounting itconst checkout = await client.createCheckout();// Sidebarconst result = await checkout.mount('#buttons');// Embeddedconst result = await checkout.mount({ paymentSelection: '#buttons', paymentScreen: '#form'});These are the key differences:
- v1 requires a
checkoutinstance, created withclient.createCheckout(), before callingmount() - v1 passes container selectors directly to
mount()instead of nesting inside{ containers: { ... } } - v1 supports
autoProcessing— when enabled,mount()returns the completed payment result instead of a transient token
Completing Transactions
const token = await up.show({ containers: { paymentSelection: '#buttons' }});const result = await up.complete(token);// Automatic (default when completeMandate is in session)const checkout = await client.createCheckout({ autoProcessing: true });const result = await checkout.mount('#buttons');// result is the completed transaction — no need to call complete()// Manual - similar to v0const checkout = await client.createCheckout({ autoProcessing: false });const token = await checkout.mount('#buttons');const result = await checkout.complete(token);These are the key differences:
- v1 supports
autoProcessing— when enabled,mount()returns the completed transaction result directly, eliminating the separatecomplete()call - v1 mirrors the v0 manual flow when
autoProcessingis disabled
Events
v0: No event system — the integration relies on promise resolution or rejection from show() and complete().
v1: Full event system at both client and integration level:
// Client-level — centralized error trackingclient.on('error', (err) => { console.error(`[${err.source}] ${err.code}: ${err.message}`);});// Checkout-level — granular lifecycle eventscheckout.on('ready', (data) => { console.log('Available methods:', data.availablePaymentMethods);});checkout.on('paymentMethodSelected', (data) => { console.log('Selected:', data.type);});checkout.on('error', (err) => { console.error('Checkout error:', err.code);});Cleanup
up.hide(); // Hide UIup.dispose(); // Clean up resourcescheckout.unmount(); // Remove UI from page (can remount later)checkout.destroy(); // Permanent cleanupclient.destroy(); // Destroy client and clear all event listenersThese are the key differences:
- v1 distinguishes between
unmount()(reversible) anddestroy()(permanent) - Both
destroy()calls are idempotent client.destroy()emits a"destroyed"event before cleanup
Error Handling
try { const token = await up.show({ containers: { paymentSelection: '#buttons' } });} catch (err) { console.error(err.reason, err.message);}// Same error class, same propertiestry { const checkout = await client.createCheckout(); const result = await checkout.mount('#buttons');} catch (err) { console.error(err.reason, err.message);}The UnifiedCheckoutError class and its reason codes are unchanged between v0 and v1.
Migrating Triggers
If your v0 integration uses triggers, the migration is similar to checkout.
const trigger = up.createTrigger('CLICKTOPAY', { containers: { paymentScreen: '#screen' }});const token = await trigger.show();const trigger = client.createTrigger('CLICKTOPAY');const result = await trigger.mount('#screen');These are the key differences:
- v1 creates triggers from the
client, not fromUnifiedPayments - v1 passes the container to
mount(), not to the constructor - v1 renames
show()tomount()
Quick Migration Checklist
Use this checklist to migrate your integration from v0 to v1:
- Replace
new Accept(session).unifiedPayments()withawait VAS.UnifiedCheckout(session) - Update your server to call
/uc/v1/sessionsinstead of/up/v1/capture-contexts - Update any
consumerAuthenticationboolean value to one of the v1 enum values (3DS,NONE,PASSKEY) - Replace
up.show(options)withcheckout = await client.createCheckout(); checkout.mount(target) - Update container options:
{ containers: { paymentSelection, paymentScreen } }becomes direct arguments tomount() - Replace
up.complete(token)withcheckout.complete(token)or useautoProcessing: trueto complete transactions automatically - Replace
up.hide()withcheckout.unmount() - Replace
up.dispose()withcheckout.destroy()andclient.destroy() - Add event listeners for observability, such as
client.on('error')andcheckout.on('ready')
Thanks for your feedback!
Last published: September 29, 2026