Skip to content

Webhooks ​

Full reference for the delivery envelope, headers, and the catalog of events Paytami can send you. For how to register an endpoint and verify the signature, see the webhooks guide.

The event envelope ​

Every delivery is a POST with this body:

json
{
  "id": "evt_7c1a2b3d4e5f60718293a4b5",
  "type": "payment.succeeded",
  "created_at": "2026-08-28T15:10:00.000Z",
  "data": { "...": "the resource matching this event type" }
}
FieldDescription
idUnique event identifier, evt_ prefix. Use it to deduplicate.
typeOne of the values in the event catalog.
created_atISO 8601, UTC.
dataThe affected resource, in the same shape the public API returns.

Headers on every delivery ​

HeaderDescription
Paytami-Signaturet=<unix>,v1=<hmac_hex> — see signature verification.
Paytami-Event-IdSame id as the body (evt_...), to deduplicate without parsing the JSON first.
User-AgentPaytami-Webhooks/1.0.

Event catalog ​

EventFires when
payment.succeededA charge completed successfully.
payment.failedA charge attempt failed.
payment.canceledA charge was canceled before completing.
refund.succeededA refund processed successfully.
chargeback.openedA chargeback was opened on a payment.
chargeback.wonA chargeback resolved in the merchant's favor.
payout.completedA payout landed in the merchant's bank account.
payout.failedA payout failed.

You can subscribe to any subset of these events when registering your endpoint, or leave it empty to receive all of them.

payment.succeeded / payment.failed / payment.canceled ​

data is the same Payment object returned by GET /v1/payments/{id}:

json
{
  "id": "pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "status": "captured",
  "currency": "GTQ",
  "amount": "15000",
  "paytami_fee": "435",
  "net_amount": "14565",
  "checkout_url": "https://app.paytami.com/api/v1/checkout/pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "created_at": "2026-08-28T15:04:00.000Z"
}

refund.succeeded ​

json
{
  "id": "refund_4a1f0c2b3d4e5f60718293a4",
  "payment_id": "pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "amount": "5000",
  "currency": "GTQ",
  "reason": "requested_by_customer",
  "status": "succeeded"
}

reason is one of: requested_by_customer, duplicate_charge, product_not_received, product_unacceptable, merchant_error, fraudulent, other.

chargeback.opened / chargeback.won ​

json
{
  "id": "chb_9a1b2c3d4e5f60718293a4b5",
  "payment_id": "pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "amount": "15000",
  "currency": "GTQ",
  "status": "opened"
}

status is opened or won depending on the event. The chargeback reason isn't included: it's sensitive information handled directly between Paytami and the card issuer during the dispute process.

payout.completed / payout.failed ​

json
{
  "id": "payout_c7e5b1a2d3e4f5061728394a",
  "currency": "GTQ",
  "amount": "142000",
  "status": "completed",
  "bank_account_id": "ba_2d6a9f1e2c3b4a5061728394",
  "bank_account_masked": "••••4321",
  "requested_at": "2026-08-27T10:00:00.000Z",
  "processing_at": "2026-08-27T10:05:00.000Z",
  "sent_to_bank_at": "2026-08-27T14:00:00.000Z",
  "completed_at": "2026-08-28T09:00:00.000Z",
  "failed_at": null,
  "canceled_at": null,
  "failure_reason": null
}

On payout.failed, failure_reason carries the reason and completed_at stays null.

See also ​

Official Paytami Documentation