Skip to main content

Webhooks

Reseller webhook endpoint registration management (Phase 3.W.3). A reseller registers an HTTP endpoint on its own server to receive a signed POST when the events it subscribed to occur (e.g. service.suspended, product.price_changed).

SUBSCRIPTION PATTERNS (event_types):

  • * → all events (catch-all)
  • prefix.* → namespace wildcard (service., product.) — single segment
  • exact → exact event name (service.suspended)

VALID EVENTS (V1): service.created, service.suspended, service.unsuspended, service.terminated, product.price_changed, product.stock_changed, product.disabled, credit.added. An unknown event type returns 422.

service.created (Phase 3.W.4): sent once provisioning of the ordered VPS completes and it becomes active on the Rabisu side (WHMCS domainstatus 'Pending' → 'Active'; detected via cron polling). With this event the reseller learns INSTANTLY that the service is ready (GET /orders/{id} polling remains as a fallback). Payload: {provision_id, service_id, order_id, product_id, vps_id, status='active', occurred_at, schema_version}. provision_id = the id in the POST /orders response (reseller correlation key).

credit.added (Phase 3.B): sent when credit is loaded to the reseller (admin manual credit or invoice refund). Payload: {reseller_id, amount, currency, reason (manual_credit|refund), description, related_invoice_id, new_balance, occurred_at}. This event goes ONLY to the relevant reseller (not a broadcast). Source: WHMCS tblcredit polling (bin/credit-event-emitter.php). NOTE: apply_credit (order payment) does NOT produce this event — that is written to the GET /auth/balance/movements audit in real time by OrderService.

SECRET: the plain HMAC secret in the POST response is shown ONLY once. On every delivery the dispatcher adds an X-Rabisu-Signature: sha256=HMAC header. If lost, the endpoint must be deleted and recreated.

CIRCUIT BREAKER: 5 consecutive failed deliveries automatically deactivate the endpoint (is_active=0). The reseller reactivates it with PATCH {is_active: true}.