notification_url on POST /v1/payouts, the provider POSTs a
signed event to that URL on every status transition — PENDING,
PROCESSING, PAID, REJECTED, CANCELLED. No polling required.
Subscribing
Passnotification_url on create. HTTPS only — http:// URLs are
rejected with 422 VALIDATION_ERROR.
PENDING, PROCESSING, PAID.
Event shape
data is the full Payout resource after the transition — same shape as
GET /v1/payouts/{id}. Use data.status and previous_status to drive
your handler.
Signature verification
Every webhook is signed with HMAC-SHA256 over the raw response body, using your webhook secret. The signature is sent in theX-Clevis-Signature header
as:
hmac.compare_digest in Python, crypto.timingSafeEqual
in Node.js) to avoid timing attacks.
Delivery semantics in v1
Always back your webhook handler with
GET /v1/payouts/{id} reconciliation
on a timer — in v1 because there are no retries, and in the long term to handle
out-of-order delivery and missed events from any push system.
Mock-only knobs
processing.step_seconds: 0on create — no webhooks fire, because all transitions are applied synchronously before the create response is returned. The terminal state is already in the response body.processing.step_seconds: 30(or any non-zero value) — webhooks fire on every transition, separated by that many seconds.
Testing locally
A common pattern: pointnotification_url at an ngrok
or Cloudflare Tunnel URL
running on your machine, and use a MOCK_SLOW_ external_id to make the
transitions visible at human pace.