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.

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) |

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.

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.

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.

Every click on a payment link (button or URL) mints a fresh invoice. That invoice follows the standard lifecycle:

waitingunconfirmedfinished (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.