Skip to main content

Principles

Every webhook implementation needs to cover 3 things:
  1. HMAC validation with the secret received when the webhook was created
  2. Fast response (200 OK in ≤10s)
  3. Idempotency via the x-event-id header

Code Examples

Why raw body?

The HMAC is computed over the exact bytes that NTX Pay sent. If your framework parses the JSON first (rearranging whitespace, reordering fields), the signature won’t match. Always capture the raw body as bytes before parsing.

Routing by Event and Status

The event field identifies the flow (transaction.cash_in.* / transaction.cash_out.*) and status the outcome. Filter before processing:

Retries

If you return a status ≠ 2xx (or exceed the 10s timeout), NTX Pay retries up to 5 times with exponential backoff starting at ~5 seconds. After that, the delivery is marked as failed — a manual redelivery can be requested from support.
Do not use 429 to signal rate limiting on your own service — it triggers retries and amplifies the load. Respond 503 Service Unavailable if you genuinely cannot process.

Best Practices

  • Use Redis/a database for dedupe with a TTL ≥ 24h (not in-process memory)
  • Process asynchronously: the webhook handler should only validate + enqueue
  • Monitor handler latency — target P95 < 500ms
  • Log x-event-id for auditing