Widget Integration
Embed hosted checkout with the browser widget runtime.
Use the widget runtime when your frontend needs to launch a Stafiel checkout
session. Create the checkout session first on your server, then pass the
checkoutSessionUrl from the response data to the browser.
Important: Do not put API keys in frontend or browser code.
Runtime Scripts
Load one of the browser runtimes from the widget domain for your network mode. The stable paths are:
| Runtime | Script | Global | Use when |
|---|---|---|---|
| Checkout snippet | https://widget.stafiel.com/widget/v1/checkout.js |
window.StafielCheckout |
You want a smaller helper for button binding or declarative HTML binding. |
| Widget runtime | https://widget.stafiel.com/widget/v1/widget.js |
window.StafielWidget |
You want direct control over create, open, mount, events, and cleanup. |
Checkout vs Widget
Use Checkout snippet for quick development and deployment. It is best for payment buttons, simple modal checkout, and declarative HTML binding.
Use Widget runtime when you need direct control over the checkout instance. It is best for inline checkout areas, custom lifecycle handling, event subscriptions, theme changes, or cleanup in single-page applications.
Both runtimes consume the same checkoutSessionUrl. The checkoutSessionUrl
is an opaque hosted checkout URL. Do not parse, rebuild, or modify it.
Checkout Snippet Example
Use checkout.js when you want to bind checkout behavior to a button or DOM
node without managing the lower-level widget instance yourself.
<button id="pay-now">Pay now</button>
<script src="https://widget.stafiel.com/widget/v1/checkout.js"></script>
<script>
window.StafielCheckout.bind('#pay-now', {
checkoutSessionUrl: 'https://pay.stafiel.com/pay/ps_your_session_token',
mode: 'modal',
theme: 'light'
});
</script>
Checkout Snippet API
| Method | Returns | Description |
|---|---|---|
open(options) |
Promise<CheckoutSnippetBinding> |
Opens checkout immediately. |
bind(target, options) |
CheckoutSnippetBinding |
Binds checkout to a CSS selector or HTMLElement. |
bindAll(root?, defaults?) |
CheckoutSnippetBinding[] |
Binds every [data-stafiel-checkout] node under root. |
setTheme(target, theme) |
void |
Updates the theme for an existing binding. |
unbind(target) |
void |
Removes the click trigger listener for one binding. |
destroy(target?) |
void |
Removes one binding, or all bindings when no target is provided. |
Checkout Snippet Binding
open(), bind(), and bindAll() return binding instances.
| Method | Returns | Description |
|---|---|---|
open() |
Promise<void> |
Opens the bound checkout. |
close() |
void |
Closes the current checkout surface when supported. |
destroy() |
void |
Removes the binding and its runtime state. |
setTheme(theme) |
void |
Switches the binding between light and dark. |
update(options) |
void |
Updates the binding with new checkout snippet options. |
Checkout Snippet Options
| Option | Required | Default | Description |
|---|---|---|---|
checkoutSessionUrl |
Yes | None | Hosted checkout URL returned by your server. |
mode |
Yes | None | One of the values listed in Widget Modes. |
container |
No | Bound target | Optional container selector or element for mounted modes. |
openInNewTab |
No | true for redirect |
Controls redirect mode tab behavior. |
scale |
No | 1 |
Widget scale for non-redirect modes, clamped between 0.8 and 2.5. |
borderRadius |
No | 24 for modal, 16 otherwise |
Frame border radius in pixels, clamped between 0 and 24. |
theme |
No | light |
One of light or dark. |
autoFallback |
No | false |
Allows fallback to another mode when needed. |
onOpen |
No | None | Called when checkout opens. |
onClose |
No | None | Called when checkout closes. |
onError |
No | None | Called when checkout fails to initialize or open. |
onFallback |
No | None | Called when the runtime falls back to another mode. |
Declarative Binding
checkout.js can bind elements declared in HTML.
<div
data-stafiel-checkout
data-checkout-session-url="https://pay.stafiel.com/pay/ps_your_session_token"
data-mode="lite"
data-theme="light"
data-scale="1"
data-border-radius="16"
></div>
<script src="https://widget.stafiel.com/widget/v1/checkout.js"></script>
<script>
window.StafielCheckout.bindAll();
</script>
Supported data attributes:
| Attribute | Required | Description |
|---|---|---|
data-stafiel-checkout |
Yes | Marks the element for bindAll(). |
data-checkout-session-url |
Yes, unless supplied in bindAll defaults |
Hosted checkout URL. |
data-mode |
Yes | One of the values listed in Widget Modes. |
data-container |
No | Selector for a separate mounted container. |
data-scale |
No | Widget scale for non-redirect modes. |
data-border-radius |
No | Frame border radius in pixels. |
data-theme |
No | light or dark. |
data-auto-fallback |
No | Boolean value: true, false, 1, or 0. |
data-open-in-new-tab |
No | Boolean value used by redirect mode. |
Widget Runtime Example
<div id="stafiel-payment"></div>
<script src="https://widget.stafiel.com/widget/v1/widget.js"></script>
<script>
const widget = window.StafielWidget.create({
checkoutSessionUrl: 'https://pay.stafiel.com/pay/ps_your_session_token',
mode: 'inline',
container: document.getElementById('stafiel-payment'),
theme: 'light'
});
widget.mount();
</script>
Use open() for redirect and modal mode. Use on() to subscribe to widget
events, and clean up subscriptions or widget instances when your page no longer
needs them.
<script>
const widget = window.StafielWidget.create({
checkoutSessionUrl: 'https://pay.stafiel.com/pay/ps_your_session_token',
mode: 'modal',
theme: 'light'
});
const unsubscribe = widget.on('order.payment.received_fullpaid', function (event) {
console.log('Order paid', event);
});
await widget.open();
// Later, for example when leaving a single-page app route:
unsubscribe();
widget.destroy();
</script>
Widget Options
| Option | Required | Default | Description |
|---|---|---|---|
checkoutSessionUrl |
Yes | None | Hosted checkout URL returned by your server after creating a checkout session. |
mode |
Yes | None | One of the values listed in Widget Modes. |
container |
Required for mounted modes | None | HTMLElement used by inline, lite, or micro. You may also pass it to mount(container). |
openInNewTab |
No | true for redirect |
Controls whether redirect mode opens a new browser tab. |
scale |
No | 1 |
Widget scale for non-redirect modes, clamped between 0.8 and 2.5. |
appearance.borderRadius |
No | 24 for modal, 16 otherwise |
Frame border radius in pixels, clamped between 0 and 24. |
autoFallback |
No | false |
Allows the runtime to fall back to another mode when the requested mode cannot be opened. |
theme |
No | light |
One of light or dark. |
The Widget runtime delivers events through widget.on(event, handler) rather
than option-level callbacks. See Widget Methods and
Events.
The Checkout snippet accepts a flat borderRadius option. The Widget runtime
nests the same setting under appearance.borderRadius.
Internal debug, preview, and advanced timeout options are intentionally not part of the public integration surface.
Widget Runtime API
| Method | Returns | Description |
|---|---|---|
create(options) |
WidgetInstance |
Creates a widget instance from a hosted checkout session URL and widget options. |
Widget Modes
| Mode | Call | Default frame size | Description |
|---|---|---|---|
redirect |
open() |
Hosted checkout page | Opens the hosted checkout URL in a new tab by default, or in the current tab when openInNewTab is false. |
modal |
open() |
828 x 648 px |
Opens checkout in an overlay. |
inline |
mount() |
272 x 384 px |
Mounts a full checkout frame into your page. |
lite |
mount() |
368 x 144 px |
Mounts a compact checkout frame. |
micro |
mount() |
256 x 128 px |
Mounts the smallest checkout frame for compact payment areas. |
The shown frame size applies when scale is 1. All non-redirect modes accept
values from 0.8 through 2.5. The runtime scales the complete checkout surface
uniformly. Modal checkout may be constrained by the available browser viewport
on smaller screens. widget.js and checkout.js share this non-redirect scale
contract; no legacy scale mapping is applied.
Widget Methods
| Method | Returns | Description |
|---|---|---|
open() |
Promise<void> |
Opens redirect or modal mode. |
mount(container?) |
Promise<void> |
Mounts inline, lite, or micro mode. |
close() |
void |
Closes the current widget surface when supported. |
destroy() |
void |
Removes listeners, frames, and runtime state for the instance. |
setTheme(theme) |
void |
Switches the instance between light and dark. |
on(event, handler) |
() => void |
Subscribes to a widget event and returns an unsubscribe function. |
Events
Widget events are browser-side UI and status signals. The full event set below
is available through the Widget runtime on(event, handler) API. Checkout
snippet integrations receive lifecycle signals through onOpen, onClose,
onError, and onFallback options in
Checkout Snippet Options. Use webhooks or the order
query APIs for server-side state changes.
| Event | Description |
|---|---|
widget.ready |
The widget instance or iframe runtime is ready. |
widget.opened |
Checkout was opened or mounted. |
widget.closed |
Checkout was closed. |
widget.error |
The widget failed to initialize, mount, open, or load. |
widget.fallback |
The runtime switched to another mode. |
order.created |
The checkout surface reported an awaiting-payment order. |
order.payment.detected |
The checkout surface reported a detected payment. |
order.payment.received_fullpaid |
The checkout surface reported a fully paid order. |
order.payment.received_underpaid |
The checkout surface reported an underpaid order. |
order.payment.received_overpaid |
The checkout surface reported an overpaid order. |
order.payment.confirmed |
The checkout surface reported payment confirmation. |
order.paid |
The checkout surface reported a paid status. |
order.settled |
The checkout surface reported settlement. |
order.expired |
The checkout surface reported expiration. |
order.closed |
The checkout surface reported closure. |
order.compliance_hold |
The checkout surface reported a compliance hold. |
Event payload fields vary by event type.
| Field | Description |
|---|---|
event |
Event name. Present on every widget event. |
version |
Widget event payload version. Present on every widget event. |
timestamp |
Event timestamp. Present on every widget event. |
orderId |
Order ID when available. |
paymentToken |
Payment token when available. |
mode |
Active widget mode. Present on lifecycle, error, and order events. |
reason |
Error or fallback reason. Present on widget.error and widget.fallback. |
recoverable |
Whether the error can fall back to another mode. Present on widget.error. |
fromMode |
Original widget mode. Present on widget.fallback. |
toMode |
Fallback widget mode. Present on widget.fallback. |
status |
Order status. Present on order events. |
payload |
Event-specific payload. Present on order events and some error events. |
Security Notes
Create checkout sessions on your server. The browser widget only needs the
checkoutSessionUrl.
Keep the widget script host aligned with the checkout session's network mode. If you use a testnet checkout session URL in widget code, use the testnet widget script host and testnet checkout configuration.