Two delivery channels
Orchestrate can deliver an event two ways. Both carry the same events and the same payloads; what differs is scope and whether the delivery is signed.
Pick a project endpoint when you want one handler for everything, a
webhook_url when you
want the notification tied to the resource you just created — or both.
For anything that moves value on your side — fulfilling an order, crediting a wallet — use a
project endpoint and verify the signature, or re-fetch the resource. Never trust an unsigned
body.
Events
Every event below is delivered on both channels. On a project endpoint you subscribe per event; thesubscribe as column is the name you pick in your dashboard.
Subscribing to
all on a project endpoint gives you every event above, including future
ones. Key your handler on the event field rather than on a fixed list.
A failed attempt does not mean a failed payment.
payment.attempt.failed can be followed
by a successful attempt on the same payment. Act on payment.* for the final outcome and
treat payment.attempt.* as detail.Both refund events share the payment_refunded subscription; read the event field to
tell a full refund from a partial one.Delivery guarantees
Deliveries are retried up to five times on failure. Delivery is at-least-once and order is not guaranteed: you can receive the same event twice, or a later event before an earlier one. Build your handler accordingly:- Be idempotent. Key on the payment id plus the event name and ignore repeats.
- Do not rely on order. Read the current status from the payload or the API rather than inferring it from the sequence of events.
- Respond quickly. Return
2xxas soon as you have stored the event; do the work afterwards.
Headers
Project endpoint deliveries:webhook_url deliveries:
webhook_url deliveries:
Verifying a project endpoint
Each project endpoint has its own secret, shown when you create it in the dashboard. Deliveries carry an HMAC signature computed over the raw request body with that secret. Compare it in constant time, against the raw body — not a re-encoded version of the parsed JSON.Payloads
Payment events
Attempt events
Same shape, with more detail onattempt — it adds amount, country, next_action,
completed_at, failed_at and created_at — and a shorter payment block that carries
only created_at among the timestamps.
Refund events
Payout events
When a webhook never arrives
If your endpoint was down or a payment looks stuck, do not poll in a loop. Ask Orchestrate to re-check the payment with the provider: see Requery. For payouts, useGET /payouts/{id}/sync — see Payouts.