Payment links
Create reusable payment buttons and shareable links.
A payment link is a reusable template stored in the dashboard. Each time a buyer clicks the button or visits the public URL, payzum creates a fresh invoice from the template — so you define the price and currency once and share the link everywhere.
What a payment link is
Unlike a direct invoice (POST /v1/payment), which is a one-shot deposit address, a payment link is a stable record with its own ID (e.g. link_xxx). It holds the price, currency, and chain configuration. When a buyer interacts with it, a new invoice is minted automatically.
Link types:
| Type | Typical use |
|------|-------------|
| payment | One-time purchase (product, service) |
| donation | Open or fixed-amount contribution |
| subscription | Recurring plan (each cycle creates an invoice) |
Managing links in the dashboard
Create and manage payment links under Dashboard → Merchants → [your merchant] → Payments / Donations / Subscriptions.
Each link detail page shows:
- The public buy URL (
/buy/<linkId>) — share this directly with buyers or post it on social media. - A ready-to-paste HTML embed snippet (button + widget script).
- A plain
<a>fallback for environments where you cannot inject JavaScript. - Recent invoices minted from this link.
Embedding a button on your site
Paste the snippet from the dashboard (or construct it manually) on any page where you want a payment button:
<!-- Payment button -->
<button data-payzum-link="link_xxx"
style="padding:.6rem 1.2rem;border:0;border-radius:8px;
background:#0ea5e9;color:#fff;font:600 14px system-ui;
cursor:pointer">
Pay now
</button>
<script src="$PAYZUM_BASE/widget/v1/payzum.js" async></script>Replace $PAYZUM_BASE with your payzum API host (e.g. https://merchant.payzum.com). When the buyer clicks the button, the widget creates an invoice from the link and opens the checkout modal in-page — no redirect needed.
$PAYZUM_BASE is your payzum API host — the same host that serves /v1/payment. SRI hashes are intentionally omitted: the widget script is served from a versioned path (/v1/), so pin the version through the path rather than a content hash.
window.Payzum.openLink
If you need programmatic control — for example, attaching the checkout to a non-button element or passing dynamic order metadata — call openLink directly:
// Load the widget script once (e.g. in <head>)
// <script src="https://merchant.payzum.com/widget/v1/payzum.js" async></script>
document.getElementById('pay-btn').addEventListener('click', () => {
window.Payzum.openLink(
'link_xxx',
{ order_id: 'ORDER-789', order_description: 'Annual plan' },
{
onSuccess: (invoiceId) => {
window.location.href = '/thanks?invoice=' + invoiceId
},
onCancel: (invoiceId) => console.warn('Cancelled', invoiceId),
onExpired: (invoiceId) => alert('Session expired — please try again'),
},
)
})The body argument accepts the same optional fields as POST /v1/payment: order_id, order_description, success_url, cancel_url, and purchase_id. The link's price, currency, and chain settings are not overridable from the client.
Plain link (no JavaScript)
For environments where you cannot inject a script tag (email newsletters, static site generators, third-party embeds), use the plain buy URL as a standard anchor:
<a href="https://merchant.payzum.com/buy/link_xxx" target="_blank" rel="noopener">
Pay now
</a>The buyer is taken to the hosted checkout in a new tab. No widget script is required.
Invoice lifecycle after a link click
Every click on a payment link (button or URL) mints a fresh invoice. That invoice follows the standard lifecycle:
waiting → unconfirmed → finished (or expired / failed / cancelled)
The IPN webhook is delivered to the merchant's configured webhook URL when the invoice status changes. See Webhooks overview for signature verification and retry behaviour.