Agent skill

Nuvemshop (Tiendanube) Webhooks Skill

Receive and verify Nuvemshop (Tiendanube) webhooks. Use when setting up Nuvemshop webhook handlers, debugging x-linkedstore-hmac-sha256 signature verification, or handling store events like order/created, order/paid, order/cancelled, product/updated, or app/uninstalled.

Install this skill

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


When to Use This Skill

  • How do I receive Nuvemshop / Tiendanube webhooks?
  • How do I verify Nuvemshop webhook signatures?
  • How do I handle order/created, order/paid, or order/cancelled events?
  • Why is my x-linkedstore-hmac-sha256 verification failing?
  • Setting up a webhook receiver for a Nuvemshop app

Verification (core)

Nuvemshop signs the raw request body with HMAC-SHA256 keyed on your app's client secret (the OAuth app secret from the Partners Portal) and sends the digest hex-encoded in the x-linkedstore-hmac-sha256 header. Compute the HMAC on the exact raw bytes before JSON parsing and compare timing-safe.

There is no official SDK — verification is manual in every language.

Node:

const crypto = require('crypto');

function verifyNuvemshopWebhook(rawBody, hmacHeader, clientSecret) {
  if (!hmacHeader) return false;
  const expected = crypto
    .createHmac('sha256', clientSecret)
    .update(rawBody)          // rawBody is a Buffer/string of the exact bytes
    .digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(hmacHeader), Buffer.from(expected));
  } catch {
    return false;             // length mismatch = invalid
  }
}

Python:

import hmac, hashlib

def verify_nuvemshop_webhook(raw_body: bytes, hmac_header: str, client_secret: str) -> bool:
    if not hmac_header:
        return False
    expected = hmac.new(client_secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(hmac_header, expected)

Important: Respond with a 2XX status within 3 seconds. Nuvemshop retries on timeout/non-2XX (immediately, then ~5/10/15 min, then exponential backoff ×1.4, up to 18 attempts over 48h). Do slow work asynchronously.

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

Thin Payloads — Fetch the Full Resource

Nuvemshop payloads are intentionally minimal. A typical body is:

{ "store_id": 123456, "event": "order/created", "id": 999888 }

Only store_id, event, and (for resource events) a resource id are sent. To get the full record, call the REST API scoped to that store, e.g. GET https://api.tiendanube.com/v1/{store_id}/orders/{id} with the store's access token.

Common Event Types

Events use resource/action format.

EventTriggered When
order/createdNew order placed
order/paidOrder payment received
order/cancelledOrder cancelled
order/updatedOrder modified
order/fulfilledOrder fulfilled/shipped
product/createdNew product added
product/updatedProduct modified
product/deletedProduct removed
customer/createdNew customer registered
app/uninstalledApp uninstalled from the store

For the full event list, see references/overview.md and Nuvemshop's webhook docs.

Environment Variables

NUVEMSHOP_CLIENT_SECRET=your_app_client_secret   # OAuth app "Client secret" from the Partners Portal

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 nuvemshop --path /webhooks/nuvemshop

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Aug 4, 2026

View on GitHub →