Overview
Webhooks push real-time notifications to your server when events occur on EU Rails, so you do not have to poll the API. You create a subscription with an HTTPS endpoint URL and a list of event types; Balansas thenPOSTs a signed
JSON payload to that URL whenever a matching event fires.
Create a subscription
POST /webhooks with your HTTPS url and the eventTypes you want. The
response returns a signing_secret — store it now (see Signing below).Verify the signature
On every delivery, recompute the HMAC and compare it to the
X-Webhook-Signature header before trusting the payload.The endpoint URL must be HTTPS and must not resolve to a private or reserved
address. Subscriptions are validated at creation and again before every
delivery.
Event types
EU Rails (Fiat Republic) subscriptions can listen for these event types:Payment
Payment
payment.created, payment.status_updated, payment.completed,
payment.failedFiat Account
Fiat Account
fiat_account.created, fiat_account.status_updated,
fiat_account.balance_updatedVirtual Account
Virtual Account
virtual_account.created, virtual_account.status_updated,
virtual_account.balance_updatedEnd User
End User
end_user.created, end_user.status_updated, end_user.review_requiredPayee
Payee
payee.created, payee.status_updatedHMAC signing & verification
Every delivery carries three headers:| Header | Description |
|---|---|
X-Webhook-Id | The subscription ID the event was delivered for. |
X-Webhook-Timestamp | Unix timestamp (seconds) when the delivery was signed. |
X-Webhook-Signature | sha256=<hex> — the HMAC of the signed message. |
{timestamp}.{body} (the timestamp, a literal dot, then the raw request body),
keyed by your subscription’s signing secret, and hex-encoded with a sha256=
prefix.
To verify, recompute the HMAC using the exact raw request body (do not
re-serialize the parsed JSON), the X-Webhook-Timestamp value, and your signing
secret, then compare in constant time:
Delivery & retries
Your endpoint should respond with a2xx status to acknowledge receipt. Any
4xx, 5xx, or timeout marks the delivery as failed and schedules a retry with
exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | After 1 minute |
| 3 | After 5 minutes |
| 4 | After 30 minutes |
| 5 | After 2 hours |
| Final | After 24 hours |
is_active: false, with disabled_at and disabled_reason set). Re-enable it
by updating the subscription once your endpoint is healthy again.
Deliveries can be repeated due to retries or network conditions. Process events
idempotently: dedupe on the event
id and always return 2xx for an event you
have already handled.Rotating the signing secret
Rotate the secret if it may have been exposed. Rotate a webhook signing secret generates a newwhsec_… value and returns it once in the response. Update your
verification code to the new secret immediately — deliveries signed after
rotation use the new secret.
Sending a test event
Use Send a test event to a webhook to confirm your endpoint is reachable and your signature verification works. It delivers a signed payload with eventwebhook.test to your configured URL and
returns the HTTP status, response time, and any error from the attempt.
Related
List webhook subscriptions
See your configured subscriptions.
Create a webhook subscription
Register an endpoint and event types.
Rotate a signing secret
Issue a fresh signing secret.
Send a test event
Verify reachability and signing.

