Merchant API

Checkout Payments Webhook (one-time payments)

Real-time webhook notifications sent when payments are completed via KingPay's hosted checkout solution. These webhooks notify you when a customer has successfully paid for their order and you should fulfill the purchase.

Delivery & security

  • Webhooks are sent to the callback_url configured for the invoice (or project), with all your original query parameters preserved.
  • HTTP method: GET by default, POST when the invoice was created with post=1.
  • Content type: application/x-www-form-urlencoded by default, application/json when the invoice was created with json=1.
  • Webhooks are signed using HMAC-SHA256 with your project’s ipn_secret. Always verify the signature before trusting the payload.

Signature headers

  • X-CryptAPI-Signature — hex-encoded HMAC of the canonical JSON payload and timestamp.
  • X-CryptAPI-Signature-Alg — currently always HMAC-SHA256.
  • X-CryptAPI-Signature-Timestamp — Unix timestamp (seconds) used in the HMAC computation.

Sent for invoices with type = "checkout". UTXO, EVM and TRON payments send payment_status: pending progress, then confirmed, then completed when distribution succeeds. Observed confirmation counts may jump. Solana sends confirmed and completed only, with both confirmation fields set to 1 as a network stage rather than slot depth. TRON distribution waits for at least 23 confirmations for TRX or 20 for TRC20 and a successful solidified receipt, even when the merchant's confirmed threshold is lower. Credit the incoming payment once at confirmed or completed, never on pending. The invoice can still be partially paid; use invoice_status for fulfilment.

Behaviour

  • Sent for payment progress, confirmation and completed distribution. A delivery can be retried; process it idempotently.
  • is_paid is "1" only when the whole invoice is paid; otherwise it is "0", including partial payments.
  • Any extra params you added to redirect_url (e.g. ?order_id=123) are echoed in the payload.
Payload example
{
  "payment_id": "fG78jtx96ugjtu0eIbeLmFB9z0feJf9N",
  "payment_url": "https://pay.yourdomain.com/pay/fG78jtx96ugjtu0eIbeLmFB9z0feJf9N",
  "redirect_url": "https://example.com/success?order_id=12345",
  "value": "200",
  "currency": "usd",
  "is_paid": "1",
  "paid_amount": "1.23000000",
  "paid_amount_fiat": "200.00",
  "received_amount": "1.23000000",
  "received_amount_fiat": "200.00",
  "paid_coin": "trc20_usdt",
  "exchange_rate": 162.60,
  "txid": "0x123...",
  "address": "TR7NHqjeKQxGTCi8q8zy4pL8otSzgjLj6t",
  "type": "payment",
  "status": "done",
  "payment_status": "completed",
  "invoice_status": "paid",
  "confirmations": 1,
  "required_confirmations": 1,
  "external_id": "12345",
  "customer_name": "John Doe",
  "customer_email": "[email protected]"
}

Key fields

  • payment_id — unique payment identifier (invoice UID).
  • payment_url — hosted checkout URL.
  • redirect_url — original redirect URL you provided.
  • value — requested invoice amount in ordinary fiat units as a decimal string (e.g. "200" means 200 USD). Trailing zeros may be omitted.
  • Project fee surcharges can increase the crypto total shown on the hosted page; value remains the original order amount. Service fees use a gross-up calculation; network estimates are converted from native coin to payment currency and include a 10% reserve. The total is fixed when the address is issued. Paying that total closes the invoice even if actual network costs rise; paying only the base amount can leave it partially paid.
  • currency — fiat currency (e.g. usd).
  • is_paid — string "1" for a fully paid invoice, otherwise "0".
  • paid_amount — incoming crypto before fees, as a decimal string in paid_coin.
  • paid_amount_fiat — incoming fiat before fees, as a decimal string in currency, or null. Falls back to the requested invoice amount when the stored valuation is unavailable.
  • received_amount / received_amount_fiat — distributed crypto / fiat equivalent after fees, as decimal strings, only in completed webhooks. The fiat field falls back to incoming fiat when the net valuation is unavailable, and can be null. All amounts use ordinary currency units, without multiplying by 100.
  • paid_coin — which crypto was used.
  • exchange_rate — fiat per 1 coin at the time of payment.
  • txid — blockchain transaction hash.
  • type — always "payment".
  • status — "done" when fully paid.
  • external_id — your payment identifier (External ID from params).