Get started with the Web SDK
Load, secure, initialize, preload, and validate the DEUNA Web SDK in sandbox and production.
On this page
The DEUNA Web SDK is a browser script that renders payment experiences in a modal or a responsive target element. Your backend creates orders and protects private credentials; the browser receives a public API key and short-lived order token.
Integration architecture#
1. Load a pinned version#
<script
crossorigin
src="https://cdn.deuna.io/web-sdk/v1.7/index.js">
</script>The script exposes window.DeunaSDK. Pin the version in production and test upgrades in sandbox first. Do not silently rewrite the CDN URL at runtime from untrusted input.
For a single-page application, load the script once at the document level. If you load it dynamically, resolve a shared promise so concurrent routes do not add duplicate tags.
function loadDeunaSdk() {
if (window.DeunaSDK) return Promise.resolve(window.DeunaSDK);
if (window.__deunaSdkPromise) return window.__deunaSdkPromise;
window.__deunaSdkPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://cdn.deuna.io/web-sdk/v1.7/index.js';
script.crossOrigin = 'anonymous';
script.onload = () => resolve(window.DeunaSDK);
script.onerror = () => reject(new Error('DEUNA Web SDK failed to load'));
document.head.append(script);
});
return window.__deunaSdkPromise;
}2. Initialize the environment#
await DeunaSDK.initialize({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
env: 'sandbox',
});Use sandbox for integration tests and production for live traffic. Production is the SDK default, but setting env explicitly prevents accidental cross-environment tokens and credentials.
3. Choose loading strategy#
| Strategy | Use when | Tradeoff |
|---|---|---|
| Preload one likely widget | The checkout page can initialize before the final click. | Fast opening; consumes network and browser resources earlier. |
| Initialize, then open on demand | The experience is rarely used or the page must minimize early work. | Simpler lifecycle; customer sees the widget loading state. |
await DeunaSDK.initialize({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
env: 'sandbox',
preloadWidgets: [
{
widget: 'payment',
params: {
language: 'en',
callbacks,
},
},
],
});
// Once your backend returns the token, reveal the prepared widget.
await DeunaSDK.initPaymentWidget({orderToken});Preload only the experience the customer is likely to open. The current source supports payment, elements, voucher, and nextAction preload entries.
4. Open an experience#
Content Security Policy#
Start from your application’s existing policy and allow only the DEUNA origins used by the selected environment and features. The production SDK itself loads from https://cdn.deuna.io; widget frames use the production Checkout or Elements hosts, while API and storage connections use DEUNA production endpoints. Sandbox uses the corresponding *.sandbox.deuna.io hosts.
Content-Security-Policy:
script-src 'self' https://cdn.deuna.io;
frame-src https://checkout-ux.deuna.com https://elements.deuna.com https://cdn.getduna.com;
connect-src 'self' https://api.deuna.io https://apigw.getduna.com https://elements.deuna.com;Wallets, fraud providers, APMs, fonts, images, and custom style files can require additional provider-specific origins. Add only the origins exercised by your configured integration; verify the browser console in sandbox and keep the policy under source control. Do not add broad wildcards to silence violations.
Responsive host and accessibility#
Modal mode uses the viewport on screens up to 600 px wide. For embedded mode, provide a fluid host and update its height from onResize.
#deuna-payment {
width: 100%;
min-width: 0;
min-height: 32rem;
}
@media (max-width: 600px) {
#deuna-payment { min-height: 100dvh; }
}Keep zoom enabled, do not trap focus outside the widget, restore focus after closure, and test keyboard navigation plus 200% text zoom.
Sandbox acceptance checklist#
- The script loads once and failure produces a recoverable UI.
- Sandbox keys and order tokens never reach production, or vice versa.
- Modal and target modes work at 320 px width and with a keyboard only.
- Success, decline, close, timeout, refresh, and network interruption are handled.
- 3DS and APM popups or redirects are not blocked by CSP or iframe sandboxing.
- Logs exclude tokens, customer details, and payment data.
- Your backend—not the callback—decides whether fulfillment is allowed.