Skip to main content

Webhook & Test-Mode Strategy

This page is the single source of truth for the webhook and test-mode design across Debitura's public APIs. It covers how test and live subscriptions work, the CI loop primitives available on each API, and where each auxiliary capability fits.


Core design principle

Core CI-loop primitives are symmetric across the Customer API and Collection Partner API. Auxiliary primitives exist where they are genuinely needed, not for symmetry's sake.


Test vs live subscriptions

See Test vs Live Subscriptions for how isTestMode works, immutability, and running test and live subscriptions simultaneously.


The 4-step CI loop

The complete test loop follows four steps:

CREATE → DRIVE → ASSERT → RESET
  1. CREATE — create a test case with isTest: true and a run-scoped tag
  2. DRIVE — call advance to move the case to a target lifecycle state
  3. ASSERT — call GET /webhooks/events?caseId={id} to verify what fired and was delivered
  4. RESET — call DELETE /test/cases?tag={tag} to hard-delete all run data

See CI Testing for the full implementation with code examples.


Per-API capability matrix

Core CI loop — symmetric (Customer API + Collection Partner API)

PrimitiveCustomer APICollection Partner APINotes
Create test casePOST /cases with isTest: truePOST /managed-cases with isTest: trueTag the case for scoped cleanup
Advance lifecyclePOST /test/cases/{id}/advancePOST /test/cases/{id}/advanceSame request body
Hard-delete by tagDELETE /test/cases?tag=DELETE /test/cases?tag=
Hard-delete by IDDELETE /test/cases/{id}DELETE /test/cases/{id}
Delivery historyGET /webhooks/eventsGET /webhooks/eventsFilter by caseId and since
Replay by event IDPOST /webhooks/events/{id}/replayPOST /webhooks/events/{id}/replayRe-enqueues the exact original payload

fire — symmetric (Customer API + Collection Partner API)

POST /test/webhooks/fire fires a named event type for a test case without advancing the lifecycle. Use it to test your handler in isolation — emit case.closed without actually closing the case.

Valid event types differ by API because the event vocabularies differ:

APIValid event types
Customer APIcase.created, case.updated, case.closed, payment.created, chat.created
Collection Partner APIcase.assigned, case.updated, case.closed, payment.created, chat.created
note

payment.created returns 422 if no payments exist on the case. chat.created returns 422 if no chats exist.

replay-last-event — Collection Partner API only (by design)

POST /test/cases/{id}/replay-last-event replays the most recent webhook event for a case without needing to look up the event ID.

This endpoint is Collection Partner-only and is intentionally not ported to the Customer API. It was added as a stopgap when the Collection Partner API lacked a delivery history endpoint. Now that GET /webhooks/events is available on both APIs, replay-last-event is redundant — but it is kept for backward compatibility and documented here as a thin convenience wrapper over GET /webhooks/events + POST /webhooks/events/{id}/replay.

Use replay-by-id in new integrations. Use replay-last-event only when you genuinely don't want to enumerate event history.

Referral Partner API — separate model

The Referral Partner API uses a separate isolated test-environment model. There are no in-row test cases or isTestMode subscriptions. Instead, test events are fired via POST /v1/webhooks/test against the dedicated Referral Partner test environment at testreferral-api.debitura.com.

The Customer API and Collection Partner API CI-loop primitives described above do not apply to the Referral Partner API.


Other webhook capabilities

Signature verification

Every delivery includes an X-Debitura-Signature header for HMAC-SHA256 verification. See Signature Verification for implementation details and code examples.

Retry and auto-disable

Failed deliveries use up to 8 total delivery attempts with exponential backoff. A subscription is automatically disabled after all 8 attempts fail, or if your endpoint returns 410 Gone. See Retry Behavior for the full schedule.

Idempotency

The event id field in every payload is a stable UUID. Track it to deduplicate replayed or retried deliveries. Replayed events also include the header X-Debitura-Replay: true. See Idempotency: webhook consumption.

Local development

Use a tunneling tool (ngrok, cloudflared) to expose a local port and point a test subscription at it. See Local Development.