Guides
Receive webhooks
Pass a webhook_url when creating a payment and Trevi POSTs an order.confirmed event to it once the sale settles on your wallet. The callback carries no value — it is a signed statement about something that already happened between two other wallets.
One event exists today: order.confirmed, sent when a payment transitions to paid. The body is exactly { event, payment_id, external_order_id, merchant_id, amount_sats, payment_hash, paid_at }. Match it to your order with external_order_id — the reference you supplied at create time.
Headers: x-trevi-event: order.confirmed and x-trevi-signature: <base64>, where the signature is HMAC-SHA256(secret, raw_body) encoded as BASE64 (not hex). Capture the raw request body before parsing JSON — re-serialising changes the bytes and breaks the HMAC.
The signing secret is a per-merchant webhook secret, generated on your first delivery. It is NOT your API key. There is currently no public endpoint that returns it — contact support@trevi.cash if you need it to verify signatures. Until you hold the secret, treat the callback as an untrusted hint: confirm the sale independently with GET /api/v2/payments/:paymentId before releasing goods.
Delivery: a POST with a 10-second timeout. Any non-2xx response counts as a failure. Trevi retries up to 5 times total, spaced at least 5 minutes apart, then gives up. Respond 2xx as soon as you have durably recorded the event.
Deliveries are at-least-once. Dedupe on payment_id so a repeat delivery is harmless.
A webhook Trevi cannot deliver never reverses anything. The customer paid your wallet; that is a settled fact regardless of whether your server heard about it. Reconcile with GET /api/merchants/payments if you suspect a missed delivery.
# Sample delivery to your webhook_url:
#
# POST /webhooks/trevi
# x-trevi-event: order.confirmed
# x-trevi-signature: <base64(hmac-sha256(secret, raw_body))>
# content-type: application/json
#
# {
# "event": "order.confirmed",
# "payment_id": "pay_abc123def456abc123def456abc123de",
# "external_order_id": "order-12345",
# "merchant_id": "merch_abc123",
# "amount_sats": 150000,
# "payment_hash": "9f2c...",
# "paid_at": "2026-08-13T12:04:11.000Z"
# }