Webhook event catalogue
Hubpay webhook events cover payment requests, payments, onboarding, RFI cases and app connections. Subscribe only to the event families required by your integration.
Overview
Hubpay emits webhook events to inform your system about real-time changes to resources such as payment requests, payments and onboarding.
You can subscribe to events by registering a webhook endpoint. Once subscribed, we’ll send signed HTTPS POST requests
to your server with the relevant event data
so your system can react in real-time (update UI, trigger fulfilment, etc.).
Event catalogue
The events you can subscribe to depend on your account type. Account owners receive collection events for payment requests, payments and payouts. Partner accounts receive onboarding events for accounts and documents they manage.
Collection events (account owners)
| Event | When it triggers |
|---|---|
v1.collection.payment_request.created | The payment request is first generated |
v1.collection.payment_request.part_paid | A partial payment is captured but the payable balance > 0 |
v1.collection.payment_request.paid | The request balance reaches 0 |
v1.collection.payment_request.cancelled | The request is cancelled by the user or after a payment is rejected |
v1.collection.payment_request.payment.created | Reserved for future use. Intended to represent an initial state |
v1.collection.payment_request.payment.pending | Payment processing started; for crypto this is queued immediately before received on confirmation |
v1.collection.payment_request.payment.received | Crypto confirmed on-chain, card captured, or bank funds received; crypto compliance may still be in progress |
v1.collection.payment_request.payment.completed | Payment completed and funds credited to the Hubpay wallet; applicable crypto compliance gates cleared |
v1.collection.payment_request.payment.failed | Payment failed due to error or rejection |
v1.collection.payment_request.payment.reversed | Reserved for future use. Intended to represent a post-completion reversal |
v1.collection.payment_request.payment.payout.pending_approval | Payout is awaiting approval |
v1.collection.payment_request.payment.payout.initiated | Payout has been initiated |
v1.collection.payment_request.payment.payout.paid | Payout has been paid |
v1.collection.payment_request.payment.payout.failed | Payout has failed |
For event timing and the recommended crypto confirmation signal, see Payment lifecycle and webhooks. Payload details: Payment request | Payments | Payouts
Onboarding events (partners only)
| Event | When it triggers |
|---|---|
v1.onboarding.account.created | On successful creation of new account |
v1.onboarding.account.signed_up | On acceptance of account sign-up details |
v1.onboarding.account.submitted | On submission of account sign-up details (incl. documentation) for review and decision |
v1.onboarding.account.approved | On approval of account sign-up details (incl. documentation) |
v1.onboarding.account.rejected | On rejection of account sign-up details or documentation |
v1.onboarding.account.onboarded | The account is fully onboarded and able to transact |
v1.onboarding.document.approved | Document has been reviewed and accepted 1 |
v1.onboarding.document.declined | Document has been reviewed and not accepted 1 |
v1.onboarding.document.validation_warnings | Automated validation flagged concerns 1 |
For details: Account onboarding | Document
RFI events (partners only)
Lifecycle events on RFI cases and per-document decisions on files attached to those cases. The two families are independent: subscribe to whichever you need.
| Event | When it triggers |
|---|---|
v1.rfi.case.opened | A new RFI case has been raised against the customer |
v1.rfi.case.closed | All items resolved; ops closed the case |
v1.rfi.case.cancelled | Ops cancelled the case (no further customer action required) |
v1.rfi.document.approved | A file attached to an RFI document request has been approved 1 |
v1.rfi.document.declined | A file attached to an RFI document request has been declined 1 |
v1.rfi.document.validation_warnings | Automated validation flagged concerns on an RFI-attached file 1 |
For details: RFI case | RFI document
Connection events (partners only)
Lifecycle events on partner app connections: fired when a customer accepts or declines a connection the partner requested, or when an active connection is revoked.
| Event | When it triggers |
|---|---|
v1.connection.accepted | The customer approved the connection in the Hubpay Business app. It is now ACTIVE and the partner can make scoped on-behalf-of calls. |
v1.connection.declined | The customer declined the connection request. It will not become active. |
v1.connection.revoked | The connection was ended by the partner or the customer. On-behalf-of access has stopped. |
For details: Connection
Ordering and delivery guarantees
Hubpay dispatches events in logical lifecycle order: for example, payment.pending is always sent before payment.received, which is always sent before payment.completed. Events are queued in order and delivered sequentially.
However, delivery order to your endpoint is not strictly guaranteed. Network conditions, retry timing, and concurrent delivery can cause events to arrive out of sequence. Your integration should be designed to handle this.
Best practices
- Use
createdAtfor ordering. Every event includes acreatedAttimestamp set at the time the event was produced. Use this to determine the true sequence, not the order events arrive at your endpoint. - Always fetch the latest state. Events are thin notifications: they tell you something changed, not what the current state is. When you receive an event, call the relevant API (for example, Get payment request) to retrieve the authoritative resource state before taking action.
- Don't hard-code lifecycle assumptions. Your handler may receive
payment.completedbeforepayment.receivedhas arrived. If you query the API on receipt ofpayment.completed, you'll see the resource is already in its final state: the earlier event becomes informational. - Design for idempotency. The same event may be delivered more than once (see Retry strategy). Use the event
idto deduplicate and ensure processing an event twice has no adverse effect.
Webhooks tell you "something happened": they are a prompt to check the latest state via the API. The API is always the source of truth.
Event format
Hubpay uses thin events: minimal, lightweight webhook messages designed for stability, safety, and forward compatibility.
What are thin events?
Thin events are compact and granularly scoped. Instead of sending large payloads each event includes:
- Stable identifiers (e.g. paymentRequestId) and resource type
- A minimal data object (often optional)
- No embedded resource bodies
Each webhook is an HTTPS POST with a small, JSON payload:
{
"id": "<event-uuid>",
"event": "v1.collection.payment_request.created",
"createdAt": "2025-06-25T13:04:11Z",
"accountId": "<your-account-uuid>",
"relatedObject": {
"id": "<resource-uuid>",
"type": "collection.payment_request",
"url": "v1/collections/payment-requests/<id>"
},
"data": {
// Optional: varies by event
}
}
Every message is signed for verification (see Verifying webhook signatures) and automatically retried on failure (see Retry strategy).
Receiving events
To start receiving and handling webhooks:
-
Register your webhook URL
CallPOST /v1/webhookswith your callback URL and secret key. -
Listen for signed webhook events
We will send HTTPSPOSTrequests to your registered endpoint for every relevant event. See our webhook registration reference API for the expected payload/request. -
Verify the signature
See Verifying webhook signatures -
Process the event
- Inspect the
eventfield (e.g.v1.collection.payment_request.created) - Take appropriate action in your system (e.g. update UI, trigger fulfilment, notify user)
- See the event catalogue for supported values
- Inspect the
-
Return
HTTP 2xx
A2xxresponse acknowledges successful receipt. Any other response triggers automatic retries with exponential backoff (see Retry strategy).