API ReferenceWooCommerceSDKssoonWebhookssoon

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.

Example
# 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"
#   }