Skip to main content

Webhooks

You can specify multiple webhook URLs when creating your Payment Intents, Refunds, or Payouts. There is no way to specify webhook URLs from the dashboard; the list of webhooks must be provided on each resource creation that supports them.

By default each endpoint receives every event. To receive only a subset, set the events array on that webhook endpoint (for example ["payment.success"]). The type and status fields are always present (and sub_status on payment, refund, and payout events), so you can also filter in your own code.

When a customer disputes a payment with their bank or wallet, the payment intent's webhook endpoints also receive dispute.created, dispute.updated, and dispute.closed. See Dispute Webhook.

Authentication​

On each webhook endpoint you can provide an optional secret, which is sent in a header named Orchestrapay-Webhook-Secret so you can authenticate the request.

Delivery and retries​

We POST each event to your endpoints in real time. A delivery is successful only when your endpoint returns a 2xx status code within 3 seconds. Return the status code before running any heavy processing: if your endpoint takes longer than 3 seconds we abort the connection and count the delivery as failed, as we do for any non-2xx response, redirect, or connection error.

When a delivery fails we retry it with exponential backoff for up to 3 days, after which we stop. In a sandbox we retry a few times over a few hours. Each endpoint you configured is delivered to, and retried, independently.

Deliveries are at-least-once: the same event may arrive more than once, and events are not guaranteed to arrive in the order they occurred. Use the envelope id (evt_...) to deduplicate, and rely on each object's status rather than delivery order to determine the current state.

Payload​

The core of the webhook payload has the same properties, albeit each status or sub-statuses may have additional properties.

You can find the exhaustive list of payloads in the Webhook Payloads page.