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_id

Tip — 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_url

Modal 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