Quick start
Issue an API key and create your first invoice.
Issue your first API key and create a test invoice in five minutes. The examples below run against the production API; swap the base URL for https://staging.payzum.com to use the sandbox environment (note: sandbox keys are separate — see that page for how to get one).
1. Create a merchant and copy the API key
Sign in to the dashboard, create a merchant, and copy the API key shown on the reveal page. The plaintext key is shown once, so store it somewhere safe — payzum only retains a SHA-256 hash and the last 4 characters for identification.
2. Set environment variables
The rest of this page assumes PAYZUM_BASE and PAYZUM_API_KEY are exported in your shell.
export PAYZUM_BASE=https://merchant.payzum.com # staging/sandbox: https://staging.payzum.com
export PAYZUM_API_KEY=<MERCHANT_API_KEY>3. Verify connectivity
Hit the unauthenticated liveness endpoint. A 200 response means the API is reachable.
curl -s "$PAYZUM_BASE/v1/status"4. List supported currencies
The /v1/currencies endpoint returns every supported (chain, symbol) tuple.
curl -s "$PAYZUM_BASE/v1/currencies" | jq '.currencies | length'5. Create your first invoice
A successful response returns 201 and the full payment object including a deposit address. The identifier is returned as payment_id (not id) — store it to track the invoice. See the API reference for the complete response schema.
curl -X POST "$PAYZUM_BASE/v1/payment" \
-H "x-api-key: $PAYZUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"price_amount": 49.99,
"price_currency": "usd",
"pay_currency": "usdttrc20",
"order_id": "ORDER-12345",
"ipn_callback_url": "https://merchant.example.com/payzum/ipn"
}' | jq .payment_idTip — skip the currency picker entirely: send "pay_currency": "all"
and the buyer chooses the currency on the hosted checkout, limited to your
accepted-tokens allowlist.
Your integration never has to know which tokens you accept.
5b. Show the payment — three integration surfaces
Every invoice comes back with payment_id and invoice_url. From there you
choose how the buyer pays (you can try all three interactively in the
dashboard's Integration playground):
Redirect — simplest. Send the buyer to invoice_url; pass success_url
/ cancel_url at create time to get them back:
window.location.href = payment.invoice_urlModal widget — the checkout opens in an overlay on your own page:
<script src="https://merchant.payzum.com/widget/v1/payzum.js"></script>
<script>
Payzum.open(payment.payment_id, {
onSuccess: (id) => (window.location.href = '/thanks?invoice=' + id),
onExpired: (id) => alert('Invoice expired — please retry'),
})
</script>Inline widget — the checkout renders inside an element you control:
Payzum.openInline(payment.payment_id, document.getElementById('pay-here'), {
onSuccess: (id) => (window.location.href = '/thanks?invoice=' + id),
})Widget callbacks are UI hints only — fulfilment must always key off the signed IPN webhook. Full widget API: Embeddable widget.
6. Read it back
Replace inv_abc123 with the payment_id returned in step 5, or use your own order_id.
curl -s -H "x-api-key: $PAYZUM_API_KEY" \
"$PAYZUM_BASE/v1/payment/inv_abc123" | jq .If you poll this endpoint to track the invoice, treat finished, expired, and failed as the terminal payment_status values — anything else (waiting, partially_paid) means the invoice is still open. See the Invoice lifecycle for the full status map.
Next steps
- Set up signed IPN webhooks so your backend learns about payment status changes.
- Browse the full API reference for every endpoint and parameter.
- Add the hosted checkout if you don't want to render the payment UI yourself.