Elements and card vault for Web
Integrate DEUNA Elements for card vault, Click to Pay, Apple Pay, and Google Pay on responsive web experiences.
On this page
initElements opens a focused credential experience without requiring Payment Widget. Use it to vault a card, run Click to Pay, or launch a configured native wallet.
Choose an Elements type#
| Type | Purpose | Identity or order context |
|---|---|---|
vault | Tokenize or select a stored card. This is the default when types is omitted. | userToken for an authenticated user, or userInfo; an orderToken can add amount and installment context. |
click_to_pay | Open the Click to Pay experience. | Customer identity and merchant configuration are required. |
APPLE_PAY | Launch Apple Pay after availability succeeds. | Order context and configured wallet credentials. |
GOOGLE_PAY | Launch Google Pay after availability succeeds. | Order context and configured wallet credentials. |
Vault a card#
await DeunaSDK.initElements({
orderToken,
userInfo: {
firstName: 'Ada',
lastName: 'Lovelace',
email: 'ada@example.com',
},
types: [{name: 'vault'}],
callbacks: {
onSuccess: (credential) => useCredentialResult(credential),
onError: ({type, metadata}) => showRecovery(type, metadata.code),
onClosed: () => restorePaymentMethods(),
onCardBinDetected: ({cardBin, cardBrand}) => updateCardOffers(cardBin, cardBrand),
onInstallmentSelected: ({installmentPlanOptionId}) => rememberPlan(installmentPlanOptionId),
},
});Experience flow#
Preload Elements#
await DeunaSDK.initialize({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
env: 'sandbox',
preloadWidgets: [
{
widget: 'elements',
params: {
types: [{name: 'vault'}],
language: 'en',
callbacks,
},
},
],
});
// Add the order or user context and reveal the prepared experience.
await DeunaSDK.initElements({orderToken, userToken});Initialization parameters and the later call are merged by the SDK. Put stable configuration in the preload entry and the freshest tokens in initElements.
Parameters#
| Parameter | Required | Purpose |
|---|---|---|
types | No | Experience selection; defaults to vault. |
orderToken | Flow-dependent | Order context for amount, installments, payment, or wallet launch. |
userToken | Flow-dependent | Authenticated DEUNA user context. |
userInfo | Flow-dependent | Partial customer identity: firstName, lastName, and email. |
callbacks | No, recommended | Success, error, close, event, resize, BIN, and installment handlers. |
mode + target | No | Embedded target presentation instead of the default modal. |
walletConfig | Advanced | Approved explicit Apple Pay or Google Pay configuration. |
behavior | No | Supported tokenize, purchase, split-card, and visibility behavior. |
language, styleFile, widgetExperience | No | Localization and supported appearance overrides. |
domain | No | Controlled host override; omit in standard production integrations. |
Tokenize or purchase#
The credit-card Elements behavior supports tokenize or purchase:
behavior: {
paymentMethods: {
creditCard: {
flow: 'tokenize',
},
},
}Use tokenize when the merchant flow only needs a reusable credential. Use purchase only with the required order and merchant configuration. Keep the backend responsible for deciding how the credential may be used.
Native wallets#
Check availability before rendering your button, then launch the matching type directly from the customer gesture:
const wallets = await DeunaSDK.getWalletsAvailable({orderToken, userInfo});
applePayButton.hidden = !wallets.includes('APPLE_PAY');
applePayButton.addEventListener('click', () => {
DeunaSDK.initElements({
orderToken,
userInfo,
types: [{name: 'APPLE_PAY'}],
callbacks,
});
});See Wallet availability for platform values, caching, and troubleshooting.
Embedded and controlled modes#
Use mode: 'target', target, and onResize for an embedded experience. When your page owns the primary action, set hidePayButton: true, call isValid(), then await submit(). Disable the outer button while submission is pending.
await DeunaSDK.initElements({
orderToken,
types: [{name: 'vault'}],
mode: 'target',
target: '#credential-entry',
hidePayButton: true,
callbacks: {
onResize: ({height}) => {
document.querySelector('#credential-entry').style.height = `${height}px`;
},
onSuccess: useCredentialResult,
onError: showRecovery,
},
});Migrate legacy secure fields#
Earlier documentation described modularPaymentCredentialsStorage, mountPaymentCredentialStorage, and a separate sdk.deuna.io secure-field bundle. Those names are not present in the audited current Web SDK public types or implementation. Do not copy the legacy initialization or field-mounting snippets into a new integration.
The maintained credential surface is hosted Elements through DeunaSDK.initElements:
| Legacy responsibility | Maintained approach |
|---|---|
Load sdk.deuna.io/.../main.min.js | Load the pinned current cdn.deuna.io/web-sdk/.../index.js bundle from Get started |
Initialize a Deuna or deunaSDK.init instance | Call DeunaSDK.initialize once with the public API key and explicit environment |
| Mount independent PAN, expiry, or CVV fields | Open hosted initElements({types: [{name: 'vault'}]}) in modal or embedded target mode |
| Own a merchant submit button | Use hidePayButton, isValid(), and submit() in the supported controlled mode |
| Parse a legacy credential event | Use onSuccess, onError, onClosed, and the dedicated BIN/installment callbacks |
| Reuse a legacy checkout session | Pass the current orderToken, userToken, or userInfo required by the chosen flow |
Hosted Elements owns the sensitive input UI. The current public SDK does not expose a one-to-one API for mounting each card field into unrelated merchant DOM nodes. If your approved PCI scope or product design requires independent field ownership, stop the migration and confirm a supported architecture with DEUNA before implementation.
When migrating, run the old and new experience only in separate controlled test cohorts. Never initialize both against the same customer action or attempt to copy values from legacy secure frames into Elements.
Security and operations#
- Do not read, mirror, or log card fields rendered by Elements.
- Send the result only to the merchant backend operation that needs it.
- Expire merchant sessions and SDK state together when the customer signs out.
- Reconcile an order after an interrupted purchase-mode flow.
- Treat
onSuccessas a client result, not permission to use a credential outside the customer’s consent and merchant contract.