Payouts events

Webhook Event Model

Vendy sends these events for payouts and transfers. Every payout sends payout_received when it's created, then one more event when it finishes. To receive them, create a webhook subscribed to the payout events, or to all.

EventSent whenPayout status
payout_receivedThe payout is created and your wallet is debitedpending
payout_completedThe bank confirms the payoutcompleted
payout_failedVendy declines the payout and your wallet is refunded. This is finalfailed
payout_cancelledThe payout is cancelled before it is processed and your wallet is refundedcancelled
📘

A bank rejection isn't final

If a bank rejects a payout, its status changes to failed, but no webhook is sent and your wallet isn't refunded yet. Vendy can retry it through another bank, and it may still end as completed.

Treat payout_completed, payout_failed and payout_cancelled as the final outcomes. If you poll Get Payout Details and see failed, wait for one of these events before you send the money again.

Payload

FieldTypeDescriptionNullable
event.typeEnum(String)payout_received, payout_completed, payout_failed or payout_cancelledfalse
dataPayoutThe payout. data.refid identifies itfalse

The request has an x-signature header. See Validating Webhook Signatures.

{
  "event.type": "payout_completed",
  "data": {
    "id": 1734,
    "uid": 7,
    "businessId": 6,
    "walletId": 39,
    "amount": 5000,
    "refid": "ebb8c13f-8e59-4d63-b214-09f3225b8cf1",
    "bankId": 644,
    "channel": "bank",
    "currency": "NGN",
    "meta": {
      "fee": [
        {
          "fee": 10.75,
          "reason": "payout-charge",
          "percent": false
        }
      ],
      "bank": {
        "id": 644,
        "uid": 7,
        "type": "bank",
        "email": null,
        "bankname": "GUARANTY TRUST BANK",
        "businessId": 6,
        "defaultBank": false,
        "beneficiaryname": "ADA OKAFOR",
        "beneficiarycountry": "ng",
        "maskedaccountnumber": "*****456789",
        "createdAt": "2026-04-29T13:49:01.000Z",
        "updatedAt": "2026-04-29T13:49:01.000Z",
        "deletedAt": null
      },
      "total": 5010.75
    },
    "status": "completed",
    "providerId": null,
    "provider": null,
    "reason": null,
    "createdAt": "2026-10-20T09:14:02.000Z",
    "updatedAt": "2026-10-20T09:16:40.572Z",
    "deletedAt": null
  }
}

The other events have the same shape, with status set as in the table above.