Webhooks
Webhook delivery is implemented as an opt-in durable worker. Set BILLING_WEBHOOK_DELIVERY_ENABLED=true only after configuring a signing credential reference such as env:BILLING_WEBHOOK_SIGNING_SECRET in the merchant integration settings and mounting that environment variable in the worker. The flag defaults to disabled, and imports never start delivery automatically.
Each generated event is expanded into one durable delivery per matching webhook. A stable delivery ID is sent as X-Webhook-Id; X-Event-Id identifies the source event and X-Retry-Count starts at zero. Payloads are signed with HMAC-SHA256 in X-Belegwerk-Signature. Secrets are resolved only from env:BILLING_WEBHOOK_* references and are excluded from attempts and audit records.
The worker accepts HTTP 200, 201, 202 and 204. Other responses, redirects, timeouts and network errors are retried with an exponential schedule for at most twelve retries and no longer than two days. Every attempt is append-only and records the payload hash, pinned destination IP, result and correlation ID. Leases prevent two workers from claiming the same due delivery.
Before connecting, the worker resolves every address for the HTTPS hostname and rejects the entire delivery if any result is private, loopback, link-local, metadata, mapped-private, multicast or otherwise reserved. It pins the selected public address into the TLS connection while preserving the configured hostname for certificate verification, never follows redirects, and never buffers a response body. Query strings and fragments are rejected so credentials cannot leak through stored targets or delivery logs. DNS resolution is repeated on each retry. HTTP Basic authentication is supported only with an environment-backed username:password credential; Azure auth remains fail-closed until its adapter is implemented. Before every request, the worker recomputes the exact payload digest and rejects a mismatch.
Run WebhookDeliveryJob.perform_later from the deployment scheduler or queue worker. The job scans pending events, creates missing destination deliveries idempotently, and processes a bounded batch. Receivers should persist an inbox before processing, de-duplicate by X-Webhook-Id, tolerate retries and out-of-order delivery, and fetch authoritative current state rather than treating an event as a full resource snapshot.
The synthetic test suite performs no external requests. Production firewall and queue deployment, credential provisioning, receiver verification, and an operator-observed delivery rehearsal remain activation gates.