Payment Webhooks
Payment webhooks let Bead send real time payment status updates to your system. Instead of polling the API, your server receives a POST request whenever a payment’s status changes.
Webhook notifications are configured at the terminal level and are typically used together with the Payments and Reporting APIs.
When to use payment webhooks
Use payment webhooks when you want to:
Update orders or invoices as soon as a payment completes
React to
underpaid,overpaid,expired, orinvalidstatesTrigger downstream workflows such as fulfilment, refunds, or support tickets
Track payments without polling
/Payments/tracking/{trackingId}or Reporting endpoints
Webhooks provide the event feed. The Payments and Reporting APIs provide the full history and current state if you need to re-read data.
Configuring the webhook URL
Payment webhooks are configured per terminal.
You can set the webhook URL in two ways:
Using the Terminal or Boarding APIs
When creating or updating a terminal, provide the webhook URL field.
This tells Bead where to send payment status updates for that terminal.
Through Bead support
If you do not have access to the Boarding API or prefer assistance, contact Bead with your terminal identifier and desired webhook URL.
Once configured, every payment associated with that terminal will send status updates to the configured webhook URL.
Event delivery
For each payment update, Bead sends a POST request to your webhook URL.
General behaviour:
Method: POST
Content type:
application/jsonOne event per status change for a payment
Retries if your endpoint does not return
200 OK
You should:
Log every webhook request for debugging and audit
Validate the request and payload before acting on it
Return
200 OKas soon as you have safely processed the event. Failing to do so may result in repeated attempts.
Payload format
Payment status events are delivered as JSON. The exact shape depends on the internal payment status response, but conceptually it matches the PaymentStatusResponse schema in the API.
Typical fields include:
trackingIdIdentifier created when you callPOST /Payments/crypto. Used to correlate requests and webhooks.paymentCodeShort code that identifies the payment on the hosted page and in Reporting.statusCodeCurrent payment status. Uses thePaymentStatusenum:createdprocessingcompletedunderpaidoverpaidfullyRefundedpartiallyRefundedexpiredinvalidcancelled
amountsObject that contains requested and paid amounts, including currency details. It mirrors thePaymentUpdatePaymentAmountsstructure.referenceanddescriptionOptional fields that echo the reference and description you passed when creating the payment.receivedTimeTimestamp for when the payment reached its final or current state.
An example payload in the integration guide is simplified as:
{
"trackingId": "4f181348293946cfa39b5846078c9bbc",
"paymentCode": "bAKbqtcuP5",
"statusCode": 2,
"amounts": {
...
}
}In the public API, statusCode is represented as a PaymentStatus string value such as "completed" rather than a numeric code.
Status codes
Internally, the integration guide references numeric status codes, but in the API and webhooks you will use the PaymentStatus enum values. The important statuses for webhooks are:
completedPayment completed successfully.underpaidCrypto amount received is below the requested amount.overpaidCrypto amount received is above the requested amount.expiredThe payment expired before being fully paid.invalidThe payment reached an invalid state, for example due to conflicting or incorrect on-chain activity.
For user facing behaviour, you can map these to friendly descriptions, for example “Payment expired” or “Payment amount too low”.
Recommended handling flow
When your webhook endpoint receives a payment status event:
Log the request
Store headers and payload for debugging and reconciliation.
Validate the request
Verify the request came from Bead, using your preferred verification strategy.
Validate that required fields such as
trackingId,paymentCode, andstatusCodeare present.
Look up the related order or invoice
Use
paymentCodeortrackingIdto locate the corresponding order.
Apply business logic based on
statusCodeA typical mapping is:
completedMark the order as paid
Trigger fulfilment or access delivery
underpaidMark the order as partially paid
Notify the customer or support about the remaining amount
overpaidMark the order as overpaid
Queue a refund or contact the customer according to your policies
expiredorinvalidMark the order as expired or invalid
Notify your support team or prompt the customer to create a new payment
Respond to the webhook
Return HTTP 200 as soon as processing succeeds.
If you encounter an error, return an appropriate status code and log the failure for later inspection.
Retry behaviour
Bead will retry webhook delivery if your endpoint does not return 200 OK. Exact retry timing is subject to change and is not guaranteed to be strictly linear. Recommended patterns:
Treat all webhook deliveries as idempotent
Use
trackingIdorpaymentCodeas an idempotency keyIf you have already processed an event for this payment and status, return
200 OKwithout side effects
Avoid long running operations inside the webhook handler
Enqueue work to a background job and return
200 OKquickly
Using webhooks with other APIs
Webhooks are often used together with:
Payment status APIs
GET /Payments/tracking/{trackingId}GET /Payments/get-by-payment-code/{paymentCode}
Reporting APIs
GET /Merchants/{id}/paymentsGET /Partners/{id}/paymentsGET /Terminals/{id}/payments
Settlement APIs
Merchant settlements to see how payments were batched
Payment settlements to see settlement amounts and available times
Typical patterns:
Use the webhook as the trigger, then call a status or Reporting endpoint if you need more detail.
For reconciliation, run daily Reporting or Settlement jobs and use webhooks only for real time operational reactions.
Testing webhooks
To test your webhook integration:
Use the sandbox environment with a test terminal and webhook URL.
Create payments through the Hosted Payment Page or
POST /Payments/crypto.Complete payments using test wallets so that different statuses are produced, such as
completed,underpaid, andoverpaid.Verify that your webhook endpoint receives events and that your system updates orders and logs correctly.
Once testing is complete and you are ready for production, update the webhook URL for your production terminal and repeat basic validation tests in the live environment.
Last updated