ShopifyShopifyKlaviyoKanalInflateTrendtrackInfinite FulfillmentAddingwellBoostEcom AgencyThe DeployerStork MarketingTheme Copilot AIPandectesTheme FullStackCookiebotTriple WhaleRechargeIntelligemsHotjarDatafastTrustMRRPageBuilder.storeTaap.itShopifyShopifyKlaviyoKanalInflateTrendtrackInfinite FulfillmentAddingwellBoostEcom AgencyThe DeployerStork MarketingTheme Copilot AIPandectesTheme FullStackCookiebotTriple WhaleRechargeIntelligemsHotjarDatafastTrustMRRPageBuilder.storeTaap.it
ShopifyShopifyKlaviyoKanalInflateTrendtrackInfinite FulfillmentAddingwellBoostEcom AgencyThe DeployerStork MarketingTheme Copilot AIPandectesTheme FullStackCookiebotTriple WhaleRechargeIntelligemsHotjarDatafastTrustMRRPageBuilder.storeTaap.itShopifyShopifyKlaviyoKanalInflateTrendtrackInfinite FulfillmentAddingwellBoostEcom AgencyThe DeployerStork MarketingTheme Copilot AIPandectesTheme FullStackCookiebotTriple WhaleRechargeIntelligemsHotjarDatafastTrustMRRPageBuilder.storeTaap.it
Webhooks

Webhooks

The seven webhook endpoints, how each verifies its sender, and how idempotency is enforced per provider.

7 webhook endpoints. All inbound: these are endpoints BoostEcom exposes to receive events, not endpoints you register to receive ours.

| Endpoint | Sender | Idempotency key | |---|---|---| | /api/webhooks/stripe | Stripe | StripeEvent by event.id | | /api/webhooks/shopify/events | Shopify | ShopifyWebhookEvent | | /api/webhooks/shopify/customer-redact | Shopify (GDPR, mandatory) | ShopifyCustomerRedaction | | /api/webhooks/shopify/redact | Shopify (GDPR, mandatory) | ShopifyComplianceRequest | | /api/webhooks/shopify/data-request | Shopify (GDPR, mandatory) | ShopifyComplianceRequest | | /api/webhooks/resend | Resend | EmailDeliveryEvent.providerEventId | | /api/webhooks/[platform] | Chat SDK / WhatsApp | per platform |

Stripe

Every handler is idempotent on event.id, recorded in StripeEvent. A redelivery is a no-op, which matters because credit grants and plan changes run through here.

Beyond subscriptions and credits, the handler also processes the marketplace events: account.updated, charge.refunded and payout.failed for Stripe Connect.

Credit grants read metadata.amount — the pre-tax figure — never amount_total. Stripe Tax is active, so those two differ.

Shopify GDPR — the three mandatory endpoints

Shopify requires three, and they behave differently on purpose:

customers/redact raises a ShopifyCustomerRedaction barrier before answering 200. The erasure itself is drained by the gdpr-erasure cron: vector namespaces, customer links, attribution rows, archived audit payloads. completedAt is the proof of completion: a row without it is an unfulfilled obligation, and it is visible as one.

shop/redact records a ShopifyComplianceRequest that the same cron drains: credentials, vector namespaces, raw payloads archived in AuditLog, order free-text. It stamps completedAt and names in pendingSteps whatever still needs an operator.

customers/data_request is entirely manual. handledAt is only ever set by a human. Past 30 days, a row without it raises an error-level log — the system refuses to let the obligation go quiet.

Note that these three are idempotent on their own two tables, not on ShopifyWebhookEvent.

Resend

Delivery, bounces and spam complaints. Signature verified via Svix, idempotent on EmailDeliveryEvent.providerEventId.

Verification

Every endpoint verifies its sender before doing work: Stripe signature, Shopify HMAC, Svix for Resend. An unverified payload is rejected, never processed on the assumption that it probably came from the right place.

Outbound webhooks

One outbound surface exists, and it is not in the table above because it is not an inbound endpoint: status webhooks. Incident events are signed with HMAC-SHA256 and posted to URLs configured from the admin status panel.

Built on these docs?

Drop into the forum if something's unclear or wrong. Docs improve faster when readers flag the gaps.