Každá změna stavu, kterou platforma oznamuje, seskupená do kanálů níže.
Pro vývojáře / Webhooky
Podepsané HTTP notifikace o všem, co se děje ve vašem obchodě.
Objednávky, doručení, platby, spory, předplatná, zákazníci, zásoby i e-mailový marketing se samy ohlašují. Stačí jednou přihlásit koncový bod a reagovat ve vlastních systémech téměř v reálném čase.
Webhook obchodu přihlásí jednu URL k jednomu kanálu a dostává všechny jeho události.
Neúspěšná doručení se opakují s exponenciálním odstupem, než se vzdají.
Přihlášení k odběru
Webhooky obchodu
Koncové body vytvoříte v administraci v sekci Integrace / Webhooky. Každý řádek přihlašuje jednu URL k jednomu kanálu; pro více kanálů přidejte více řádků.
Každý koncový bod má vlastní podpisový tajný klíč — zobrazí se jednou při vytvoření a lze jej kdykoli obměnit na stejné obrazovce. Ověřujte ho při každém doručení.
Rozšíření
Nainstalovaná rozšíření se přihlašují k jednotlivým názvům událostí: uveďte je v poli events manifestu a platforma je doručí na webhook URL rozšíření, podepsané klíčem dané instalace. Jednotlivé odběry lze přepínat přes API rozšíření.
Obálka doručení
Každé doručení je HTTP POST s JSON tělem. Doručení webhooků obchodu obsahují integrationId řádku koncového bodu; doručení rozšíření ho vynechávají.
{
"event": "order.shipped",
"eventId": "0d9f4c1e-6c3a-4f6e-9b1a-2f8f4f1c9d2b",
"storeId": 12,
"integrationId": 7,
"schemaVersion": 1,
"payload": {
"shippingId": 9001,
"orderId": 5501,
"storeId": 12,
"status": "shipped"
},
"timestamp": "2026-08-12T09:00:01.244Z"
}Hlavičky
X-Storefront-Timestamp— čas podpisu pokusu o doručení ve formátu ISO-8601. Je zahrnut do podpisu, takže ho nelze vyměnit bez porušení ověření.X-Storefront-Signature— hex HMAC-SHA256 přes časové razítko, tečku a surové tělo požadavku, s vaším podpisovým klíčem.X-Storefront-Event-Id— stabilní id logické události, stejné napříč všemi doručeními a opakováními dané události. Zrcadlí se i v těle. Deduplikujte podle něj.X-Storefront-Delivery-Id— identifikuje jedno doručení události na koncový bod napříč všemi jeho pokusy.User-Agent—Storefront-Webhook/1.0pro webhooky obchodu,Storefront-Extension/1.0pro doručení rozšíření.
Doručování je at-least-once: opakování se podepisují novým časovým razítkem, takže platný podpis nikdy neznamená novou událost. Ukládejte zpracované hodnoty eventId a opakování přeskakujte.
Ověřování podpisů
HMAC počítejte přesně nad surovými bajty těla — JSON parsujte až po úspěšném porovnání. Odmítejte doručení starší než několik minut.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyStorefrontWebhook(rawBody, headers, signingSecret) {
const timestamp = headers['x-storefront-timestamp'];
const signature = headers['x-storefront-signature'];
if (!timestamp || !signature) return false;
// Reject stale deliveries (replay protection). 5 minutes matches the
// official verifier's default tolerance.
if (Math.abs(Date.now() - Date.parse(timestamp)) > 5 * 60 * 1000) return false;
const expected = createHmac('sha256', signingSecret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
if (expected.length !== signature.length) return false;
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));
}Autoři rozšíření mohou místo toho použít helper verifyWebhookSignature z balíčku @storefront/extension-sdk — stejné schéma s vestavěným oknem čerstvosti.
Doručování a opakování
- Pět pokusů na doručení s exponenciálním odstupem, začíná se na dvou sekundách.
- Odpověď 4xx je konečná — doručení se neopakuje. Odpovědi 5xx, síťové chyby a vypršení časového limitu se opakují.
- Pokusy vyprší po 5 sekundách u webhooků obchodu a po 10 sekundách u doručení rozšíření.
- Potvrďte libovolnou odpovědí 2xx co nejrychleji a skutečnou práci dělejte asynchronně.
- Pořadí napříč událostmi není zaručeno — spoléhejte na časová razítka a id v payloadu, ne na pořadí doručení.
Katalog událostí
Seskupeno podle kanálů webhooků obchodu. Rozšíření se přihlašují k jednotlivým názvům událostí.
Objednávky
PURCHASEorder.createdByla vytvořena nová objednávka, včetně objednávek čekajících na platbu.
Ukázka payloadu
{
"orderId": 5501,
"order": {
"id": 5501,
"storeId": 12,
"status": "confirmed",
"priceAmountMinor": "12900",
"currency": "USD",
"customerId": 31,
"customerEmail": "jane@example.com",
"createdAt": "2026-08-11T14:03:22.101Z",
"confirmedAt": "2026-08-11T14:03:22.101Z",
"cancelledAt": null,
"trackingId": null,
"items": [
{
"productId": 88,
"name": "Poster",
"quantity": 1,
"priceMinor": "12900",
"priceCurrency": "USD"
}
]
}
}order.confirmedPlatba objednávky byla vypořádána a objednávka potvrzena.
Ukázka payloadu
{
"orderId": 5501,
"confirmedByUserId": 7,
"order": {
"id": 5501,
"storeId": 12,
"status": "confirmed",
"priceAmountMinor": "12900",
"currency": "USD"
}
}order.updatedObjednávka se změnila — stav, sledování zásilky nebo jiná pole; objekt changes uvádí, co se změnilo.
Ukázka payloadu
{
"orderId": 5501,
"changes": {
"status": "shipped",
"trackingNumber": "1Z999AA10123456784"
},
"order": {
"id": 5501,
"storeId": 12,
"status": "shipped",
"trackingId": "1Z999AA10123456784"
}
}order.cancelledObjednávka byla zrušena a zásoby uvolněny.
Ukázka payloadu
{
"orderId": 5501,
"cancelledByUserId": 7,
"order": {
"id": 5501,
"storeId": 12,
"status": "cancelled",
"cancelledAt": "2026-08-11T15:20:00.000Z"
}
}checkout.completedHostovaná platební relace byla úspěšně dokončena.
Ukázka payloadu
{
"orderId": 5501,
"paymentStatus": "paid",
"amountTotalMinor": "12900",
"currency": "USD",
"providerPaymentIntentId": "pi_3PqXo42e"
}Vrácení peněz
REFUNDorder.refundedPlatba za objednávku byla vrácena, částečně nebo v plné výši.
Ukázka payloadu
{
"orderId": 5501,
"refundId": 301,
"refundedAmountMinor": "12900",
"refundedCurrency": "USD",
"isFullyRefunded": true
}Předplatné zrušeno
SUBSCRIPTION_CANCELsubscription.cancelledPředplatné doběhlo a je nyní zrušené.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"canceledAt": "2026-08-11T00:00:00.000Z"
}Předplatné se brzy zruší
SUBSCRIPTION_CANCEL_SOONsubscription.cancel_soonZákazník naplánoval zrušení na konec aktuálního období.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"currentPeriodEnd": "2026-09-01T00:00:00.000Z"
}Zákazník vytvořen
CUSTOMER_CREATEDcustomer.createdByl vytvořen nový zákaznický účet — registrace, přihlášení přes OAuth nebo povýšení hosta.
Ukázka payloadu
{
"customerId": 31,
"storeId": 12,
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Doe",
"createdAt": "2026-08-11T14:00:00.000Z"
}Produkty
PRODUCTproduct.createdDo katalogu byl přidán produkt.
Ukázka payloadu
{
"productId": 88,
"product": {
"id": 88,
"storeId": 12,
"slug": "poster",
"name": "Poster",
"priceMinor": "12900",
"priceCurrency": "USD",
"stock": 20,
"isAvailable": true
}
}product.updatedProdukt se změnil. Hromadné úpravy vyvolají jednu událost na každý dotčený produkt, označenou bulk true a seznamem změněných polí.
Ukázka payloadu
{
"productId": 88,
"bulk": true,
"changes": [
"priceMinor"
],
"product": {
"id": 88,
"storeId": 12,
"slug": "poster",
"name": "Poster",
"priceMinor": "13900",
"priceCurrency": "USD",
"stock": 20,
"isAvailable": true
}
}product.deletedProdukt byl odstraněn; payload nese poslední známý snímek.
Ukázka payloadu
{
"productId": 88,
"product": {
"id": 88,
"storeId": 12,
"slug": "poster",
"name": "Poster"
}
}inventory.restockedSledované zásoby se z nuly vrátily do kladných hodnot.
Ukázka payloadu
{
"storeId": 12,
"productId": 88,
"productOptionId": null,
"stock": 25
}inventory.out_of_stockSledované zásoby produktu nebo varianty klesly na nulu.
Ukázka payloadu
{
"storeId": 12,
"productId": 88,
"productOptionId": null
}inventory.low_stockZásoby klesly pod nastavený práh nízkého stavu produktu. Zapíná se u jednotlivých produktů; bez prahu se událost nespouští.
Ukázka payloadu
{
"storeId": 12,
"productId": 88,
"productOptionId": null,
"stock": 4,
"threshold": 5
}Obchod
STOREstore.updatedZměnila se identifikační nastavení obchodu, například vlastní doména.
Ukázka payloadu
{
"storeId": 12,
"changes": {
"domain": "shop.example.com"
},
"store": {
"id": 12,
"name": "Example Shop",
"slug": "example",
"domain": "shop.example.com"
}
}Doprava
SHIPPINGorder.shippedZásilka objednávky poprvé přešla do odeslaného stavu.
Ukázka payloadu
{
"shippingId": 9001,
"orderId": 5501,
"storeId": 12,
"status": "shipped",
"trackingNumber": "1Z999AA10123456784",
"trackingUrl": "https://tracking.example.com/1Z999AA10123456784",
"shippedAt": "2026-08-12T09:00:00.000Z"
}order.deliveredZásilka byla doručena.
Ukázka payloadu
{
"shippingId": 9001,
"orderId": 5501,
"storeId": 12,
"status": "delivered",
"trackingNumber": "1Z999AA10123456784",
"trackingUrl": null,
"shippedAt": "2026-08-12T09:00:00.000Z"
}shipping.status_changedKaždá změna stavu přepravy, s hodnotami před a po.
Ukázka payloadu
{
"shippingId": 9001,
"orderId": 5501,
"storeId": 12,
"statusBefore": "shipped",
"statusAfter": "in_transit",
"status": "in_transit",
"trackingNumber": "1Z999AA10123456784",
"trackingUrl": null,
"shippedAt": "2026-08-12T09:00:00.000Z"
}shipping.tracking_updatedBylo nastaveno nebo změněno sledovací číslo či sledovací URL.
Ukázka payloadu
{
"shippingId": 9001,
"orderId": 5501,
"storeId": 12,
"status": "shipped",
"trackingNumber": "1Z999AA10123456784",
"trackingUrl": "https://tracking.example.com/1Z999AA10123456784",
"shippedAt": null
}Předplatná
SUBSCRIPTIONsubscription.createdObjednání předplatného bylo dokončeno a předplatné se aktivovalo.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"status": "active",
"providerSubscriptionId": "sub_1PqXo4"
}subscription.renewedOpakovaná faktura byla zaplacena a vznikla objednávka prodloužení. Spouští se od druhé zaplacené faktury.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"orderId": 5610,
"invoiceId": 441,
"amountMinor": "1999",
"currency": "USD",
"periodEnd": "2026-09-11T00:00:00.000Z"
}subscription.payment_failedPlatba za prodloužení selhala. Spouští se při prvním zaznamenání každé neúspěšné faktury.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"invoiceId": 442,
"failureReason": "card_declined",
"attemptCount": 2
}subscription.resumedČekající zrušení bylo odvoláno — protějšek události subscription.cancel_soon.
Ukázka payloadu
{
"subscriptionId": 9001,
"customerId": 31,
"productId": 88,
"status": "active",
"currentPeriodEnd": "2026-09-01T00:00:00.000Z"
}Platby
PAYMENTpayment.succeededPlatba byla vypořádána, včetně metod s odloženým asynchronním potvrzením.
Ukázka payloadu
{
"paymentId": 771,
"orderId": 5501,
"storeId": 12,
"amountMinor": "12900",
"currency": "USD",
"providerPaymentIntentId": "pi_3PqXo42e"
}payment.failedPlatba definitivně selhala. Opakovatelné pokusy se neohlašují.
Ukázka payloadu
{
"paymentId": 771,
"orderId": 5501,
"storeId": 12,
"amountMinor": "12900",
"currency": "USD",
"providerPaymentIntentId": "pi_3PqXo42e",
"failureMessage": "The shopper abandoned the 3DS challenge."
}Spory
DISPUTEdispute.createdProti platbě nebo faktuře předplatného byl otevřen chargeback.
Ukázka payloadu
{
"paymentId": 771,
"orderId": 5501,
"storeId": 12,
"disputeStatus": "open",
"providerPaymentIntentId": "pi_3PqXo42e",
"source": "payment"
}dispute.updatedPoskytovatel aktualizoval otevřený spor.
Ukázka payloadu
{
"paymentId": 771,
"orderId": 5501,
"storeId": 12,
"disputeStatus": "under_review",
"providerPaymentIntentId": "pi_3PqXo42e",
"source": "payment"
}dispute.closedSpor byl uzavřen; disputeStatus říká, zda byl vyhrán, nebo prohrán.
Ukázka payloadu
{
"paymentId": 771,
"orderId": 5501,
"storeId": 12,
"disputeStatus": "won",
"providerPaymentIntentId": "pi_3PqXo42e",
"source": "payment"
}Změny zákazníka
CUSTOMERcustomer.updatedAdministrátor upravil profil zákazníka; changes uvádí dotčená pole.
Ukázka payloadu
{
"customerId": 31,
"storeId": 12,
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Doe",
"changes": [
"firstName"
]
}customer.deletedZákaznický účet byl smazán. Payload je posledním snímkem záznamu.
Ukázka payloadu
{
"customerId": 31,
"storeId": 12,
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Doe"
}E-mailový marketing
EMAIL_MARKETINGsubscriber.addedAdresa se přidala do mailing listu — veřejné přihlášení, opětovné přihlášení nebo přidání administrátorem.
Ukázka payloadu
{
"subscriptionId": 1201,
"storeId": 12,
"email": "jane@example.com"
}subscriber.confirmedOdběratel dokončil dvojité potvrzení, nebo ho potvrdil administrátor.
Ukázka payloadu
{
"subscriptionId": 1201,
"storeId": 12,
"email": "jane@example.com"
}subscriber.unsubscribedOdběratel opustil seznam, přes veřejný odkaz nebo administrátora.
Ukázka payloadu
{
"subscriptionId": 1201,
"storeId": 12,
"email": "jane@example.com"
}campaign.sentZačala rozesílka kampaně; publikum je vyhodnocené a spočítané.
Ukázka payloadu
{
"campaignId": 55,
"storeId": 12,
"name": "Fall drop",
"subject": "New arrivals",
"recipientCount": 1240
}campaign.completedKampaň dokončila rozesílku, s konečnými počty odeslaných a neúspěšných.
Ukázka payloadu
{
"campaignId": 55,
"storeId": 12,
"name": "Fall drop",
"status": "sent",
"recipientCount": 1240,
"sentCount": 1236,
"failedCount": 4
}Opuštěný nákup
CHECKOUT_ABANDONMENTcart.abandonedKošík zákazníka byl označen jako opuštěný.
Ukázka payloadu
{
"cartId": 3301,
"storeId": 12,
"customerId": 31
}checkout.expiredHostovaná platební relace vypršela nezaplacená a objednávka byla vrácena zpět.
Ukázka payloadu
{
"orderId": 5501,
"storeId": 12,
"providerPaymentIntentId": "pi_3PqXo42e"
}