Skip to main content

Support webhooks

Support webhooks notify your backend when merchant-visible ticket, refund, or chargeback state changes. They use the existing durable webhook delivery, signature, retry, and deduplication pipeline.
Prerequisites: configure a public HTTPS webhook URL and explicitly select the support events you need. New event selectors are opt-in and are never added to an existing subscription automatically.

Events

Configure support event selectors through Developer Center or during onboarding. Existing payment event selections and per-payment callback URLs are unchanged.

Payload

The signed wire body contains the durable event ID, occurrence time, resource type, public identifiers, and a small allowlist of state/reference timestamps:
data.event_type is the subscribed selector and data.type is ticket, refund, or chargeback. c_id is omitted for resources without a merchant identifier. Depending on the event, the safe optional fields are status, previous_status, payment_h_id, payment_c_id, reference, created_at, updated_at, resolved_at, closed_at, requested_at, and processed_at.
Webhooks intentionally omit comment bodies, descriptions, PII, staff identities, assignment/team data, internal tags, raw metadata, storage keys, and audit payloads. Query the relevant *.get or comments method after receiving a notification when you need current details.

Headers and signatures

Verify the exact raw request bytes before JSON parsing. Prefer V3, require a recent timestamp, and remember processed event IDs. The same logical event can be delivered more than once with new delivery metadata.

Verify a delivery

Also reject missing replay headers and timestamps outside your accepted window (five minutes is recommended). Rotate an exposed webhook secret immediately; API-key rotation does not change callback verification.

Delivery and idempotency

The resource owner commits the merchant-visible change and an outbox event atomically. Gateway then persists one webhook delivery per selected subscription and uses the durable event ID for deduplication. Temporary NATS, process, or HTTP failures are retried; repeated infrastructure failures are retained for operational recovery. Merchant endpoints must still assume at-least-once, potentially out-of-order delivery:
  1. Verify V3 and timestamp before parsing.
  2. Insert payload.id into a table with a unique constraint.
  3. Return HTTP 2xx quickly after durable local enqueue.
  4. Fetch current state by data.identifiers.h_id when processing asynchronously.
  5. Ignore older state notifications when your stored resource version/timestamp is newer.
Do not use request_id as webhook dedupe state; use the top-level event id.

Retry behavior

Any HTTP 2xx response completes an attempt. Network errors, timeouts, URL safety failures, circuit-breaker blocks, and non-2xx responses are failures. Retries use exponential backoff with jitter, so delivery order is not guaranteed.

Error handling

Best practices

  • Use a dedicated HTTPS route with raw-body capture and strict body limits.
  • Store the event id, resource public IDs, and received timestamp before acknowledging.
  • Keep one handler per event selector even if several selectors share a URL.
  • Never log signatures, raw comment content, presigned URLs, API secrets, or webhook secrets.