> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pcnaid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Shopify topics SwiftPage subscribes to, how signatures are verified, and how deliveries are handled.

# Webhooks

SwiftPage receives all Shopify webhooks at a single endpoint, `POST {APP_URL}/webhooks/shopify`, and differentiates by the `X-Shopify-Topic` header.

## Subscribed topics

| Topic | Type | Action |
| - | - | - |
| `app/uninstalled` | Lifecycle | Mark a known shop as uninstalled after a live revocation verdict; unavailable or rejected refreshes return `503` without changing state |
| `shop/update` | Store lifecycle | Re-fetch Admin GraphQL `primaryDomain` and update the persisted storefront host |
| `domains/update` | Store lifecycle | Re-fetch `primaryDomain` |
| `customers/data_request` | GDPR | Acknowledge; anonymous visitor analytics cannot be correlated to a Shopify customer identity |
| `customers/redact` | GDPR | Acknowledge; no customer-correlatable record exists |
| `shop/redact` | GDPR | Delete all shop data with generation-bound revocation proof |
| `app_subscriptions/update` | Billing | Reconcile managed App Pricing state into the subscription record and cached plan |

The three operational topics and the billing topic are registered through the Admin GraphQL API during OAuth or managed installation, and are also declared in `shopify.app.toml` so a deployed app version enrolls shops installed before a topic was added. The three GDPR topics are declared as `compliance_topics`.

## Signature verification

Every incoming webhook is verified before processing:

1. Import the app secret as an HMAC key.
2. Sign the raw request body with HMAC-SHA256.
3. Base64-encode the result.
4. Compare it against `X-Shopify-Hmac-Sha256` using a timing-safe comparison.

Required headers: `X-Shopify-Hmac-Sha256`, `X-Shopify-Topic`, and `X-Shopify-Shop-Domain`. Missing headers return `400`; an invalid signature returns `401 { "error": "Invalid webhook signature" }` before any handler side effect.

## Processing rules

1. Verify the HMAC signature at the edge, before any processing.
2. Capture the raw body and the critical headers (including `X-Shopify-Webhook-Id` for replay-safe `shop/redact` handling).
3. Validate the signed payload shape for effectful topics.
4. Route by `X-Shopify-Topic` and perform the lightweight database operation.
5. Return `200` for accepted deliveries, `401` for an invalid signature, or `503` when a retryable lifecycle condition applies.

For `shop/update`, the payload's `myshopify_domain` must match the shop header; for `domains/update`, the handler requires a flat Domain resource (`id`, `host`/`domain`, `ssl_enabled`) at the payload root and no top-level `myshopify_domain`. Malformed or relabeled payloads return `400`. Domain refresh uses a bounded budget; timeouts, Admin API failures, and compare-and-set conflicts return `503` so Shopify retries.

## OAuth callback

The callback that triggers webhook registration is `GET /auth/callback`. It validates the `state` and `hmac` parameters, exchanges the authorization code for an access token, protects the token at rest, registers the operational topics, and redirects the merchant into the embedded app.

[Pcnaid Documentation](https://docs.pcnaid.com/namespace/index.md) › [Shopify Ecosystem](https://docs.pcnaid.com/hubs/shopify-ecosystem/index.md) › [SwiftPage](https://docs.pcnaid.com/nodes/shopify/swiftpage/index.md) › [Developer](https://docs.pcnaid.com/nodes/shopify/swiftpage/developer/index)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.