Agent skill

BigCommerce Webhooks Skill

Receive and verify BigCommerce webhooks. Use when setting up BigCommerce webhook handlers, debugging Standard Webhooks signature verification, or handling store events like store/order/created, store/order/statusUpdated, store/product/updated, or store/cart/abandoned.

Install this skill

npx skills add hookdeck/webhook-skills --skill bigcommerce-webhooks


When to Use This Skill

  • How do I receive BigCommerce webhooks?
  • How do I verify BigCommerce webhook signatures?
  • How do I handle store/order/created or store/order/statusUpdated events?
  • Why is my BigCommerce webhook signature verification failing?
  • How do I create a BigCommerce webhook via the API?

How BigCommerce Webhooks Work

BigCommerce webhooks are created via API only (no dashboard UI): POST /stores/{store_hash}/v3/hooks with an X-Auth-Token OAuth access token.

Payloads are thindata carries only the resource type and id. Read the event from scope and call the REST API back to fetch the full resource:

{
  "store_id": "1000",
  "producer": "stores/abc123",
  "scope": "store/order/statusUpdated",
  "data": { "type": "order", "id": 173331 },
  "hash": "…",
  "created_at": 1561479335
}

Respond HTTP 200 immediately; do slow work asynchronously. Failed deliveries retry over ~48h, after which the hook is deactivated. If a domain's success ratio drops below 90% in a 2-minute window it is blocklisted for 3 minutes.

Verification (core)

BigCommerce documents callback signing per the Standard Webhooks spec and recommends verifying with Standard Webhooks libraries. The spec's headers are webhook-id, webhook-timestamp, and webhook-signature (v1,<base64>), with the signature computed as HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{rawBody} — note BigCommerce's own docs don't currently name the headers explicitly, state whether the feature is GA, or clarify whether signatures apply to all hooks or only app-created hooks. Log incoming headers on your first delivery to confirm. If signatures aren't present on your hooks, fall back to custom headers set at hook creation (see references/setup.md).

The signing key is your app's client secret, base64-encoded — the standardwebhooks library base64-decodes whatever you pass, so encoding the client secret first makes the raw client-secret bytes the HMAC key. Pass the raw request body — don't JSON.parse first.

Node:

const { Webhook } = require('standardwebhooks');

// base64-encode the client secret; the library decodes it back to raw bytes
const wh = new Webhook(Buffer.from(process.env.BIGCOMMERCE_CLIENT_SECRET).toString('base64'));

const event = wh.verify(rawBody, {          // rawBody = Buffer/string of the HTTP body
  'webhook-id': req.headers['webhook-id'],
  'webhook-timestamp': req.headers['webhook-timestamp'],
  'webhook-signature': req.headers['webhook-signature'],
});
// Throws WebhookVerificationError on tampering or a stale timestamp

Python:

import base64
from standardwebhooks.webhooks import Webhook

wh = Webhook(base64.b64encode(os.environ["BIGCOMMERCE_CLIENT_SECRET"].encode()).decode())

event = wh.verify(raw_body, {               # raw_body = bytes of the HTTP body
    "webhook-id": headers["webhook-id"],
    "webhook-timestamp": headers["webhook-timestamp"],
    "webhook-signature": headers["webhook-signature"],
})
# Raises WebhookVerificationError on tampering or a stale timestamp

For complete handlers with route wiring, event dispatch, and tests, see:

Common Event Types

Dispatch on the scope field:

ScopeTriggered When
store/order/createdAn order is created (storefront, control panel, app, or API)
store/order/updatedAny field on an order changes
store/order/statusUpdatedAn order's status changes
store/product/createdA product is added
store/product/updatedA product's attributes change
store/product/deletedA product is removed
store/product/inventory/updatedBase product stock level changes
store/customer/createdA new customer registers
store/cart/createdA new cart is created
store/cart/abandonedA cart sees no activity for 1+ hour

For the full scope reference, see BigCommerce Webhook Events.

Environment Variables

BIGCOMMERCE_CLIENT_SECRET=your_client_secret   # signs/verifies webhooks
# Needed only to call the REST API back for full resource details:
# BIGCOMMERCE_STORE_HASH=abc123
# BIGCOMMERCE_ACCESS_TOKEN=your_access_token

Local Development

BigCommerce requires an HTTPS endpoint on port 443, so tunnel to your local server. The Hookdeck CLI runs via npx — no install, no account required:

npx hookdeck-cli listen 3000 bigcommerce --path /webhooks/bigcommerce

Then point a hook at the tunnel URL:

curl -X POST https://api.bigcommerce.com/stores/{store_hash}/v3/hooks \
  -H "X-Auth-Token: {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"scope":"store/order/created","destination":"https://<url>/webhooks/bigcommerce","is_active":true}'

New hooks can take up to a minute to activate.

Reference Materials