Skip to main content

Webhook Payloads

This document describes the payload structure for payment, refund, and payout webhooks sent by the Orchestrapay system.

Event envelope

Every webhook is delivered as an event envelope: a small wrapper that identifies the event, with the resource itself under data. The type field follows the <object>.<event> convention (for example payment.success) and is exactly one of the names you subscribe to in the webhooks[] array.

Envelope Parameters

idstring

Unique id of this event (evt_...). Use it to deduplicate deliveries: the same event may be delivered more than once.

typestring

The event type as <object>.<event>, e.g. payment.success, refund.canceled, payout.success. The <object> prefix tells you what data contains.

created_atstring

ISO 8601 time the event was created.

dataobject

The resource this event is about. Its shape depends on type, and is documented per object below.

RESPONSE
{
  "id": "evt_eu1_9f8c2b1a7d6e4f3c8b2a1d0e5f6a7b8c",
  "type": "payment.success",
  "created_at": "2026-07-01T12:00:00Z",
  "data": {
    // object-specific fields, see below
  }
}

Payment Intent Webhook

Sent when a payment intent transitions. A payment intent can be attempted several times (a customer may retry with another card or method), so these events describe the intent, not an individual attempt. The type is one of:

  • payment.success — the intent was paid. It is now immutable.
  • payment.canceled — the intent reached a terminal, immutable canceled state: you canceled it, or it timed out end-to-end. No further attempts can be made against it.
  • payment.attempt_failed — a single payment attempt failed, but the intent is still open and can be retried. Not terminal; do not treat it as canceled.

Once you receive payment.success or payment.canceled, the intent will not change again.

The fields below are the contents of the envelope's data object.

data Parameters

payment_intentstring

The payment intent this event is about (pi_...). This is the id you pass to POST /refunds to refund the payment.

statusstring

The payment intent status: pending (still open), success, or canceled. On payment.attempt_failed this stays pending.

sub_statusstring

The detailed status of the transaction attempt that triggered this event (e.g. canceled_rejected on payment.attempt_failed, success on payment.success).

amountnumber

Payment amount in cents.

currencystring

Three-letter ISO currency code.

customeroptional, string

The attached customer (cus_...), if any.

metadataoptional, object

The metadata you attached when creating the payment intent, echoed back.

gateway_transaction_idoptional, string

The gateway's own reference for the underlying transaction, for reconciliation.

failure_reasonoptional, string

Human-readable reason on canceled payments.

RESPONSE
{
  "id": "evt_eu1_9f8c2b1a7d6e4f3c8b2a1d0e5f6a7b8c",
  "type": "payment.success",
  "created_at": "2026-07-01T12:00:00Z",
  "data": {
    "payment_intent": "pi_eu1_b8b5be0f481f42b4b7f5972118777c5f",
    "status": "success",
    "sub_status": "success",
    "amount": 15000,
    "currency": "usd",
    "customer": "cus_eu1_2c1d7ef04db08d2e5e980f3f3bc70000",
    "metadata": { "order_id": "order_123" },
    "gateway_transaction_id": "9f4c2a7e1d8b60352c1a",
    "failure_reason": null
  }
}

Refund Webhook

Sent when a refund's status changes, with type set to refund.pending, refund.success, or refund.canceled. Only refund.pending is mutable - once a refund succeeds or is canceled, it is guaranteed not to change again.

The fields below are the contents of the envelope's data object.

data Parameters

refundstring

The refund this event is about (re_...).

payment_intentstring

The payment intent that was refunded (pi_...).

statusstring

Main status of the refund (pending, success, or canceled).

sub_statusstring

Detailed status of the refund.

amountnumber

Refund amount in cents.

currencystring

Three-letter ISO currency code.

gateway_transaction_idoptional, string

The gateway's own reference for this refund, for reconciliation.

failure_reasonoptional, string

Human-readable reason on canceled refunds.

RESPONSE
{
  "id": "evt_eu1_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
  "type": "refund.success",
  "created_at": "2026-07-01T12:05:00Z",
  "data": {
    "refund": "re_eu1_582f94c6856c447b9b2cfbbd9a528c9d",
    "payment_intent": "pi_eu1_b8b5be0f481f42b4b7f5972118777c5f",
    "status": "success",
    "sub_status": "success",
    "amount": 20000,
    "currency": "usd",
    "gateway_transaction_id": "a1e8c3f60d2b95743f0e",
    "failure_reason": null
  }
}

Payout Webhook

Sent when a payout's status changes. Configure webhook_urls and an optional webhook_secret on POST /payouts. Orchestrapay POSTs the JSON body to each URL and sends Orchestrapay-Webhook-Secret when a secret was provided.

Payouts use the same promise model as refunds: main status is pending, success, or canceled (derived from sub_status), and sub_status carries the detailed value.

When webhooks are sent

EventTypical sub_statusNotes
Payout row saved, before gateway initiationpending_createdFirst notification after create.
Gateway reports in-flight / retrypending_promiseAfter initiation when the transfer is still processing.
Transfer completedsuccessFunds sent successfully.
Gateway rejected the transfercanceled_rejectede.g. invalid account, insufficient balance.
Technical or unexpected failurecanceled_failureNon-rejection failure path.

A single POST /payouts may produce multiple webhooks (for example pending_created, then pending_promise or success, depending on the gateway response). The event type is payout.pending, payout.success, or payout.canceled.

note

Payouts are a release candidate. Payout events use the same envelope, but the data object below still carries legacy resource fields (uuid, numeric id, gateway) pending its own 202607 alignment.

data Parameters

uuidstring

Public payout identifier (same as `payout_uuid` in create responses).

idnumber

Internal payout ID.

statusstring

Main status: `pending`, `success`, or `canceled` (first segment of `sub_status`).

sub_statusstring

Detailed payout status.

tenant_idnumber

Owning tenant ID.

gatewaystring

Payout gateway identifier.

recipient_idnumber

Internal ID of the linked payout recipient (not `recipient_uuid`).

amountnumber

Payout amount in cents.

currencystring

Three-letter ISO currency code.

narrationoptional, string

Transfer description from the create request.

gateway_payout_idoptional, string

Gateway reference for the transfer, when known.

gateway_auxiliary_idoptional, string

Secondary gateway reference, when provided by the gateway.

failure_reasonoptional, string

Human-readable rejection or failure message on canceled payouts.

RESPONSE
{
  "id": "evt_eu1_7c3d9e2f1a8b4c5d6e7f8a9b0c1d2e3f",
  "type": "payout.pending",
  "created_at": "2026-07-01T12:10:00Z",
  "data": {
    "uuid": "4c56e5c2-7ef0-4db0-8d2e-5e980f3f3bc7",
    "id": 301,
    "status": "pending",
    "sub_status": "pending_promise",
    "tenant_id": 1,
    "gateway": "mygateway",
    "recipient_id": 88,
    "amount": 250000,
    "currency": "USD",
    "narration": "Weekly seller settlement",
    "gateway_payout_id": "mock-transfer-301",
    "gateway_auxiliary_id": null,
    "failure_reason": null
  }
}