Shopify webhooks
What Sumeru subscribes to
Sumeru subscribes to ~25 Shopify webhook topics. The list is declared in app installation; merchants approve at OAuth.
Topic catalog
Customer events
| Topic | Use |
|---|---|
customers/create | New customer → create Customer 360 row |
customers/update | Update Customer 360 |
customers/delete | (Pre-redact lifecycle) |
Order events
| Topic | Use |
|---|---|
orders/create | New order → attribution + journey enrollment |
orders/updated | Status changes |
orders/cancelled | Reverse fulfillment journeys |
orders/fulfilled | Trigger review-request journey |
orders/paid | Trigger post-purchase upsell |
Product / inventory
| Topic | Use |
|---|---|
products/create | Sync to multichannel feeds |
products/update | Sync changes |
products/delete | Remove from feeds |
inventory_levels/update | Real-time stock sync to marketplaces |
Cart events
| Topic | Use |
|---|---|
carts/create | Track for cart-recovery |
carts/update | Update tracking |
checkouts/create | Pre-purchase attribution touchpoint |
checkouts/update | Cart-abandonment trigger |
App lifecycle
| Topic | Use |
|---|---|
app/uninstalled | Trigger 30-day data retention countdown |
app_subscriptions/update | Plan-tier change |
GDPR (mandatory)
| Topic | Use |
|---|---|
customers/data_request | Export customer data |
customers/redact | Erase customer data |
shop/redact | Erase entire shop's data (after uninstall + 30d) |
HMAC verification
Shopify signs every webhook with HMAC-SHA256:
Header: X-Shopify-Hmac-Sha256: <base64>
Body: raw JSON
Verification:
import crypto from 'node:crypto';
function verifyShopifyWebhook(rawBody, hmacHeader, sharedSecret) {
const computed = crypto
.createHmac('sha256', sharedSecret)
.update(rawBody)
.digest('base64');
try {
return crypto.timingSafeEqual(
Buffer.from(hmacHeader),
Buffer.from(computed)
);
} catch {
return false;
}
}
Fail = 401, no processing.
Payload examples
orders/create (excerpt)
{
"id": 5234567890,
"email": "jane@example.com",
"created_at": "2026-05-10T14:23:00Z",
"total_price": "67.50",
"currency": "USD",
"customer": {
"id": 9876543210,
"email": "jane@example.com"
},
"line_items": [ ... ]
}
Full Shopify payload schemas: Shopify Webhook Reference.
GDPR webhook contract
Shopify mandates 3 GDPR webhooks for every app:
customers/data_request — export
When fired:
- Sumeru collects all customer data (Customer 360, events, messages, attributions, opt-ins)
- Generates JSON export
- Posts back to merchant's contact email or
data_request_urlper Shopify's contract - Logs to GdprRequest with status=
completed
SLA per Shopify: 30 days. Sumeru typically delivers within 1 hour.
customers/redact — erase
When fired:
- Run erase pipeline
- PII nulled in Customer 360
- Identity links deleted
- Active journeys exited
- Audit log written
SLA per Shopify: 30 days. Sumeru typically processes immediately.
shop/redact — full data erase
Fired 30 days after app uninstall. Removes all shop data permanently.
Idempotency
Each Shopify webhook has unique X-Shopify-Webhook-Id header.
Sumeru uses this for dedup.
Retry behavior
Shopify retries failed webhooks up to 48 hours with exponential backoff. Sumeru acks within 2 sec to avoid unnecessary retries.
Common gotchas
"Not receiving customers/redact webhooks." Verify Sumeru is registered in your Shopify GDPR webhook section. Re-install if missing.
"Order webhook arrived after Sumeru was already in maintenance." Shopify will retry; on next online cycle, queue drains.