Skip to main content
Use callbacks to wake your integration, not as proof of payment.

Callback payload

Billions sends an HTTP POST request with a JSON body:
For new integrations, data is the canonical event payload. Its fields are temporarily duplicated at the top level for backward compatibility.

Envelope fields

Invoice event fields

The request uses the Content-Type: application/json header.
The callback payload is not proof of payment. An attacker can send a request directly to a public callback endpoint. Retrieve the invoice using data.invoice_id and trust only the authenticated API response.

Events and intermediate statuses

Callbacks can therefore report intermediate statuses such as processing and aml_check. Update visible payment state if useful, but fulfill an order only after the authenticated API returns completed.

Safe callback algorithm

1

Accept the request

Parse only enough data to identify the invoice. Reject malformed requests without exposing internal error details.
2

Retrieve the invoice

Call the authenticated Billions API with the invoice ID.
3

Match your records

Confirm the retrieved invoice belongs to the expected order_no and payment attempt.
4

Apply the transition once

Update the order in a database transaction and make side effects idempotent.
5

Return promptly

Respond successfully after durable processing, or enqueue slow work for a background worker.

Security checklist

  • Keep API keys in server-side secret storage.
  • Require HTTPS for the callback endpoint.
  • Retrieve invoice state from the API before fulfillment.
  • Compare the invoice to the stored order and expected amount.
  • Treat all callback fields as untrusted input.
  • Avoid logging API keys or complete sensitive payloads.
  • Rate-limit the callback endpoint.
  • Make duplicate delivery harmless.
The Python SDK provides get_invoice_from_webhook() for every event status. Its verify_invoice_paid() helper additionally requires completed status and compares the webhook status and paid amount with the API result.

Delivery and response behavior

Your endpoint should acknowledge a callback only after the event is stored or processed durably. Billions considers delivery successful only when the endpoint returns HTTP 200; other responses and transport errors are retried. Current delivery defaults:
  • Request timeout: 10 seconds.
  • Maximum delivery attempts: 10.
  • Retry delay: no earlier than 10 seconds after the previous attempt.
  • event_timestamp stays unchanged across retries.
  • attempt and previous_attempt_timestamp identify retry deliveries.
Each request also includes:
The metadata headers identify a delivery but do not authenticate it. Always retrieve the invoice from the authenticated API before changing order state.