Lesson 5 — Receive and verify webhooks

Polling wastes requests and lags. Webhooks push each payment transition to

your server, signed so you can trust them. This lesson registers an endpoint,

passes verification, and processes events idempotently.

Register an endpoint


transxact webhooks:create \
  --url "https://you.example.com/hooks/transxact"

or use the webhook card in the Developer section. The response

contains a signing secret — store it; it is shown once.

An endpoint becomes active only after it answers the challenge event,

webhook.verified, with a 2xx.

Verify every delivery

Each delivery carries:

  • Transxact-Signature: v1=<hex>
  • Transxact-Timestamp: <unix-seconds>

The signature is HMAC-SHA256("<timestamp>.<body>") keyed with your signing

secret. Compute it over the *raw* request body — not a re-serialised copy —

and reject deliveries older than 5 minutes (replay window).

Every first-party SDK ships this verification built in; see your SDK's README

(sdks/<language>/README.md) for its verifyWebhook helper.

The events that matter

EventWhen
webhook.verifiedOnce, after registration or secret rotation
payment.processingIntent moved to processing
payment.succeededIntent reached succeeded
payment.failedIntent reached failed
disbursement.sentDaily disbursement run included you
disbursement.failedA disbursement bounced

Process idempotently

Deliveries can be retried, so the same event may arrive more than once.

Deduplicate on X-Transxact-Event-Id (also present as event_id in the

payload): record processed ids and skip repeats before running side

effects like fulfilment emails.

Exercise

1. Register an endpoint against your local server and catch the

webhook.verified challenge to activate it.

2. Force a payment to succeeded with magic values and verify your handler

checks out: signature valid, timestamp fresh, event id unseen.

3. Replay the same delivery body twice and confirm your deduplication holds.

4. Rotate the secret from the Developer section and confirm old signatures

now fail closed.

What's next

You have the full API loop. Lesson 6

covers the no-code surface — payment links — and the move to live mode.