Webhook Event Reference

1 — Where events go

Destination
How it’s configured
Scope

Terminal webhook

PUT /Terminals/{terminalId}/webhook

All payments created by the terminal

Per-payment overrides

webhookUrls array in POST /payments/crypto

That single payment only

Fan-out behaviour Bead POSTs the same payload to the terminal webhook and to each URL listed in webhookUrls.

2 — Set or update the terminal webhook

PUT /Terminals/{terminalId}/webhook
Authorization: Bearer {access_token}
Content-Type: application/json
{
  "webhookUrl":   "https://example.com/bead/webhooks",
  "signingSecret": "b5b9ee11f2b447c9b3294ff9a8f6f53c"
}
  • webhookUrl — must be HTTPS.

  • signingSecret — 32-byte hex string; store securely. Every event is HMAC-signed with this secret.

3 — Event payload & signature

x-webhook-signature: t=1752067200,s=9d6309b739a8e5b87e3c2b8d1d4fbc17e5e3c7f3c5b5a9d3e…
  • t = Unix-epoch timestamp (seconds)

  • s = HMAC-SHA256(signingSecret, rawBody)

Verify the signature before processing the JSON body.

Body (abbreviated example)

{
  "id":          "pay_123",
  "terminalId":  "TERM-123",
  "trackingId":  "trk_456",
  "statusCode":  "completed",
  "amounts":     { /* … */ },
  "transactions":[ /* … */ ]
  /* full schema in the OpenAPI spec */
}

statusCode enum values

Value
Meaning

created

Payment record opened; waiting for funds

processing

Funds detected but not yet confirmed

underpaid

Received < requested amount

overpaid

Received > requested amount

completed

Full amount confirmed (or overpay auto-accepted)

expired

Payment window elapsed, no settlement

invalid

On-chain tx can’t be matched

cancelled

Shopper cancelled checkout

4 — Delivery mechanics

Item
Value

Method

POST application/json

Timeout

10 s per attempt

Retries

Exponential back-off for 24 h (≈ 10 attempts) until any 2xx

Source IPs

Will be published; meanwhile verify the signature

5 — Best-practice checklist

  1. Verify signature & timestamp (x-webhook-signature) to block spoofed or replayed messages.

  2. Respond with HTTP 200 quickly—ideally under 1 s. Do heavy work async.

  3. Idempotency: use trackingId + statusCode to ignore duplicates.

  4. Environment isolation: separate webhook URLs for dev / staging / prod.

  5. Handle enum strings: numeric status codes were deprecated in May 2025.

6 — Roadmap

Upcoming enhancements (back-compatible):

  • JSON envelope {"eventId","eventType","created","data":{...}}

  • Additional event types such as terminal.status.changed, payment.refund.completed

Your current HMAC logic will continue to work; the signature will cover the new envelope.

Need help? Email [email protected].

Last updated