Embeddable widget
Drop the payzum checkout into any page with a script tag.
The payzum widget lets you embed a full checkout experience into any web page without redirecting the buyer away from your site. It loads via a single <script> tag and exposes a small window.Payzum API you call from your own JavaScript.
Loading the script
Add the widget script to your page — in <head> or before the closing </body>:
<script src="https://merchant.payzum.com/widget/v1/payzum.js" async></script>For the staging/sandbox environment, substitute the appropriate host:
| Environment | Script URL |
|-------------|-----------|
| Production | https://merchant.payzum.com/widget/v1/payzum.js |
| Staging/Sandbox | https://staging.payzum.com/widget/v1/payzum.js |
The script is served with Cache-Control: public, max-age=3600. The /v1/ path segment is the long-lived version contract; breaking changes ship under /v2/.
Annotating buttons with data-payzum-link
The simplest integration is to mark a button with a data-payzum-link attribute containing a payment link ID. The widget auto-scans for these elements on load and wires up the click handler for you:
<button
data-payzum-link="link_xxx"
data-payzum-amount="49.99"
data-payzum-order-id="ORDER-123">
Pay with crypto
</button>
<script src="https://merchant.payzum.com/widget/v1/payzum.js" async></script>If you add buttons to the page dynamically after the script has loaded, call window.Payzum.rescan() to pick them up.
The window.Payzum API
Once the script tag loads, the following methods are available on window.Payzum:
| Method | Signature | Description |
|--------|-----------|-------------|
| open | (invoiceId: string, options?: WidgetOpenOptions) => void | Mounts a full-screen overlay containing an iframe pointed at the hosted checkout for the given invoice. Closes on Esc, backdrop click, or a terminal status (with a 3 s auto-close grace). |
| openInline | (invoiceId: string, container: HTMLElement, options?: WidgetOpenOptions) => void | Mounts the checkout iframe inside a caller-supplied container element. No overlay and no auto-close — the merchant controls the lifecycle. |
| openLink | (linkId: string, body: object, options?: WidgetOpenOptions) => void | Creates a fresh invoice from a payment link and opens it. body accepts the same optional fields as POST /v1/payment (e.g. order_id, order_description). |
| close | () => void | Tears down the active overlay or removes the inline iframe, unbinds listeners, and fires the onClose callback. |
| rescan | () => void | Re-scans the DOM for [data-payzum-link] elements. Call after dynamically adding buttons. |
Opening an existing invoice
When your backend has already created an invoice (via POST /v1/payment), pass the returned payment_id to open:
// After your backend creates the invoice and returns its ID:
Payzum.open(invoiceId, {
onSuccess: (id) => { window.location.href = '/thanks?invoice=' + id },
onCancel: (id) => { console.warn('Buyer cancelled', id) },
onExpired: (id) => { alert('Invoice expired — please retry') },
})Opening a payment link directly
If you have a payment link ID, you can create and open an invoice in a single call without a server round-trip from your page:
Payzum.openLink('link_xxx', { order_id: 'ORDER-456' }, {
onSuccess: (id) => console.log('Paid:', id),
})Options callbacks
All callbacks in WidgetOpenOptions are optional:
| Callback | Fires when |
|----------|-----------|
| onSuccess(invoiceId) | Invoice reaches paid or overpaid. |
| onPartial(invoiceId) | Invoice reaches partial (under-payment). The widget stays open so the buyer can top up. |
| onExpired(invoiceId) | Invoice expires before payment is complete. |
| onCancel(invoiceId) | Invoice is cancelled (buyer clicked Cancel on the hosted page). |
| onClose() | The overlay was closed — by Esc, backdrop click, programmatic call, or auto-close after a terminal status. |
Emitted statuses
The widget relays the following status values from the hosted checkout via postMessage:
pending | partial | paid | overpaid | expired | cancelled
CSP requirements
If your site uses a Content Security Policy, add the payzum host to:
script-src— to load the widget script.frame-src— to display the hosted checkout iframe.connect-src— the iframe itself makes same-origin fetch requests (your policy does not need to add anything extra here unless your CSP restricts child frame fetches explicitly).
Widget callbacks (onSuccess, onCancel, etc.) are UI hints — they fire when the hosted checkout page posts a status message to the parent. The IPN webhook delivered to your server remains the authoritative source of truth for fulfilment. Do not fulfil orders based solely on widget callbacks.
Inline embedding
Use openInline to embed the checkout directly inside an element you control, with no full-screen overlay:
const container = document.getElementById('checkout-panel')
Payzum.openInline(invoiceId, container, {
onSuccess: (id) => showSuccessMessage(id),
})The merchant is responsible for removing or hiding the container after the session ends.