| Target URL | Production webhook targets must be HTTPS. Localhost HTTP is accepted only when the webhook service is not running in production mode. | Use HTTPS callbacks for real app installs and reserve localhost HTTP for local test environments. | services/webhook-service/src/app-lifecycle-dispatch.ts:35 + :79 |
| Signing payload and headers | The service signs `${timestamp}.${rawBody}`, sends X-LetBuyy-Hmac-SHA256 as v1=<hex>, and also sends X-LetBuyy-Signature as a legacy alias. | Verify against the raw request body bytes and strip the optional v1= prefix before timing-safe comparison. | services/webhook-service/src/app-lifecycle-dispatch.ts:52 + :57 + :90 |
| Delivery body and correlation | The POST body is { id, event_type, created_at, payload }. Headers include event ID/type, request ID, trace ID, timestamp, user-agent, and both signature headers. | Persist X-LetBuyy-Event-ID for idempotency and keep X-LetBuyy-Request-ID or X-LetBuyy-Trace-ID with support logs. | services/webhook-service/src/app-lifecycle-dispatch.ts:83 + :93 |
| Endpoint response handling | Any 2xx response marks delivery successful. Non-2xx responses record a response preview and error `Webhook endpoint returned HTTP <status>`; fetch failures have null status. | Return 2xx only after the event is durably accepted. Treat duplicate event IDs as already processed. | services/webhook-service/src/app-lifecycle-dispatch.ts:109 + :115 + :121 |
| Retry schedule | Failed queued deliveries use exponential backoff from 120 seconds, bound attempts to 0-8, and cap retry delay at 3600 seconds. | Expect retries after transient failures and make callback processing idempotent by event ID. | services/webhook-service/src/index.ts:246 |
| Queue claim and finalization | The dispatcher claims work through claim_webhook_deliveries, calls complete_webhook_delivery on success, and fail_webhook_delivery with p_retry_seconds on failure. | Do not rely on immediate delivery ordering; use event IDs and timestamps for reconciliation. | services/webhook-service/src/index.ts:788 + :810 + :818 |
| Internal dispatch routes | POST /app-lifecycle/dispatch and POST /webhook-deliveries/dispatch require X-LetBuyy-Internal-Secret and are service/internal surfaces. | [SKIP — NEEDS BACKEND/SDK] Do not call these routes from partner apps; public webhook test sender tooling is not present yet. | services/webhook-service/src/index.ts:748 + :842 |
| Subscription event filter | Lifecycle and compliance dispatch sends only to subscriptions whose event_types include the current event. Planned app subscriptions append mandatory compliance topics to every configured webhook. | Register the lifecycle topics your app needs and implement the mandatory compliance topics emitted by the platform. | services/api-gateway/src/routes/app-store/shared.ts:484 + packages/app-engine/src/index.ts:1430 |
| Compliance producer routes | POST /v1/app-store/compliance/customers/data-request, /customers/redact, and /shop/redact require merchant auth, store ownership, an idempotency key, and app webhook delivery configuration when active app subscriptions exist. | Use these routes from merchant/customer compliance workflows and dedupe events by X-LetBuyy-Event-ID on the partner callback. | services/api-gateway/src/routes/app-store/compliance-routes.ts:129 |