Preskočiť na obsah

Odchádzajúce webhooky

Overené

Webhook je opak REST a MCP: nepýtate sa vy, ozve sa MitoOps. Keď v účte vznikne udalosť, ktorú odoberáte, pošleme na vašu adresu POST s krátkou podpísanou obálkou. Obálka nesie identifikátory a stavy, nie obsah objednávky — detail si váš systém načíta cez REST rozhranie vlastným kľúčom.

Odbery spravujete v aplikácii: Nastavenia → API & MCP → Odchádzajúce webhooky. Sú dostupné od tarify Start; treba právo Odchádzajúce webhooky (čítanie alebo správa).

Endpoint má názov, adresu, zoznam udalostí a rozsah e-shopov. Pri založení dostanete tajomstvo — ukáže sa raz, potom už nikdy; kedykoľvek ho vymeníte (rotácia), staré prestane platiť okamžite.

  • Adresa musí byť verejná a cez https:// na štandardnom porte. Adresy do vnútornej siete (miestny stroj, súkromné rozsahy, metadáta cloudu, VPN rozsahy) sa odmietnu pri uložení aj pri každom doručení — meno sa prekladá znova a spojenie sa viaže na overené adresy.
  • Presmerovania sa nenasledujú. Odpoveď 3xx je zlyhanie.
  • E-shopy: všetky (aj tie, ktoré pribudnú) alebo vybrané. Udalosť z e-shopu mimo rozsahu sa nepošle.
  • Skúšobné doručenie z tlačidla pošle udalosť ping tou istou cestou ako ostrá — vrátane podpisu a zápisu do denníka.
  • Endpoint sa dá vypnúť (čakajúce doručenia sa preskočia) a zmazať (denník zostáva).
Udalosť Kedy resource.type Polia v data
order.created nová objednávka z e-shopu order order_code
order.paid objednávka označená ako uhradená order order_code
order.status_changed zmena stavu objednávky order order_code, status_id, previous_status_id
shipment.created zásielka vytvorená u dopravcu shipment shipment_id, order_code, carrier_code, tracking_number
shipment.status_changed zmena stavu zásielky (dopravca alebo obsluha) shipment shipment_id, order_code, carrier_code, status, previous_status, tracking_number
shipment.delivered zásielka doručená; navyše k shipment.status_changed shipment ako vyššie, status je DELIVERED
inventory.stock_changed pohyb zásoby položky inventory_item item_id, sku, kind
invoice.created vystavená faktúra invoice invoice_code, order_code
claim.created založená reklamácia (zákazníkom alebo obsluhou) claim claim_code, order_code
claim.status_changed zmena stavu reklamácie claim claim_code, order_code, status_id
claim.closed reklamácia uzavretá claim claim_code, order_code
ping skúšobné doručenie z tlačidla webhook_endpoint message, endpoint

Udalosti pochádzajú z tej istej obchodnej vrstvy ako automatizácie: čo spustí automatizáciu, to sa dá odoberať aj webhookom. Spätné zásielky (vratky) sa ako shipment.* neposielajú — patria k reklamácii.

Každé doručenie je JSON s verziou obálky. Nové pole môže pribudnúť bez zmeny verzie; zmena významu poľa je nová verzia.

{
"event_id": "9b2f0c1e-6d3a-4c7e-9a2b-0f1e2d3c4b5a",
"event_type": "shipment.delivered",
"version": 1,
"occurred_at": "2026-09-03T08:41:12.318Z",
"tenant": "00001",
"store": "sk",
"resource": { "type": "shipment", "id": "5521" },
"data": {
"shipment_id": "5521",
"order_code": "2026001234",
"carrier_code": "gls",
"status": "DELIVERED",
"previous_status": "IN_TRANSIT",
"tracking_number": "GLS123456789"
}
}
  • event_id je jedinečné pre udalosť. Ak tú istú udalosť odoberajú dva vaše endpointy, dostanú to isté ID. Opakovaný pokus nesie to isté ID a to isté telo.
  • store je kód e-shopu (market) — ten istý, aký používa REST.
  • tenant je identifikátor vášho účtu v MitoOps.
Content-Type: application/json
User-Agent: MitoOps-Webhooks/1
X-MitoOps-Event: shipment.delivered
X-MitoOps-Event-Id: 9b2f0c1e-6d3a-4c7e-9a2b-0f1e2d3c4b5a
X-MitoOps-Timestamp: 1756888872
X-MitoOps-Signature: v1=3f1a…c9e0
X-MitoOps-Delivery: 184

Podpis je HMAC-SHA256 kľúčom = tajomstvo endpointu nad reťazcom:

<X-MitoOps-Timestamp> + "." + <presné telo požiadavky>

Výsledok je hexadecimálny a v hlavičke stojí s predponou verzie v1=. Časová značka je unixový čas v sekundách.

Overujte nad surovým telom požiadavky (bajty tak, ako prišli), nie nad znovu serializovaným JSON-om — každá zmena medzery či poradia kľúčov podpis zneplatní. Porovnávajte v konštantnom čase a odmietnite správy staršie než 5 minút.

import { createHmac, timingSafeEqual } from 'node:crypto';
function overMitoOpsWebhook({ tajomstvo, hlavicky, suroveTelo, teraz = Math.floor(Date.now() / 1000) }) {
const cas = Number(hlavicky['x-mitoops-timestamp']);
if (!Number.isFinite(cas) || Math.abs(teraz - cas) > 300) return false; // stará alebo chýbajúca značka
const prijaty = String(hlavicky['x-mitoops-signature'] || '')
.split(',').map((s) => s.trim()).find((s) => s.startsWith('v1='));
if (!prijaty) return false;
const ocakavany = createHmac('sha256', tajomstvo)
.update(String(cas) + '.').update(suroveTelo).digest('hex');
const a = Buffer.from(prijaty.slice(3), 'hex');
const b = Buffer.from(ocakavany, 'hex');
return a.length === b.length && timingSafeEqual(a, b);
}
import hmac, hashlib, time
def over_mitoops_webhook(tajomstvo: str, hlavicky: dict, surove_telo: bytes) -> bool:
try:
cas = int(hlavicky["X-MitoOps-Timestamp"])
except (KeyError, ValueError):
return False
if abs(int(time.time()) - cas) > 300:
return False
podpis = next((s.strip() for s in hlavicky.get("X-MitoOps-Signature", "").split(",") if s.strip().startswith("v1=")), None)
if not podpis:
return False
ocakavany = hmac.new(tajomstvo.encode(), f"{cas}.".encode() + surove_telo, hashlib.sha256).hexdigest()
return hmac.compare_digest(podpis[3:], ocakavany)

Podpis pokrýva časovú značku, takže zachytenú správu nemožno neskôr poslať s novým časom. Popri kontrole času si uchovávajte event_id posledných doručení a duplicitu ignorujte: opakované doručenie je vlastnosť systému, nie chyba.

Odpoveď, opakovanie a denník

Sekcia „Odpoveď, opakovanie a denník“
  • Odpovedzte 2xx do 10 sekúnd. Telo odpovede sa nečíta. Spracovanie, ktoré trvá dlhšie, si zaraďte na pozadie a odpovedzte hneď.
  • Iná odpoveď (4xx, 5xx), timeout alebo chyba spojenia = zlyhanie a opakovanie s odstupmi 1, 5, 15, 60 a 240 minút; spolu šesť pokusov. Potom je doručenie FAILED a čaká na ručné opakovanie z denníka.
  • Odpoveď 3xx a adresa, ktorá sa prestala prekladať na verejnú sieť, sú zlyhania bez opakovania — samy sa nevyriešia.
  • Denník doručení v aplikácii ukazuje pre každý pokus stav, HTTP kód, čas, počet pokusov a udalosť. Telo správy sa v denníku nezobrazuje.
Stav Význam
PENDING čaká na pokus alebo na ďalšie opakovanie
SENT prijímateľ odpovedal 2xx
FAILED pokusy vyčerpané alebo trvalá chyba; dá sa opakovať ručne
SKIPPED endpoint bol medzitým vypnutý alebo zmazaný
  • Tajomstvo sa ukladá šifrované a nikdy sa nezapisuje do logov ani do denníka. Zobrazí sa raz; rotácia funguje aj vtedy, keď tarifa webhooky už neobsahuje — je to bezpečnostná operácia.
  • Bez osobných údajov. Obálka nesie identifikátory a stavy. Meno, adresa ani e-mail zákazníka sa neposielajú; kto ich potrebuje, číta ich cez REST s vlastným rozsahom a auditom.
  • Iba HTTPS, iba verejné adresy, bez presmerovaní. Kontrola pri uložení aj pri každom doručení chráni pred smerovaním do vnútornej siete a pred zmenou DNS.
  • Odber zakladá človek, nie kľúč. Prístupový kľúč k REST ani súhlas OAuth odber založiť nemôže: čítanie na požiadanie a trvalý prúd udalostí von sú dve rôzne oprávnenia.
  • Izolácia. Odbery aj denník ležia v priestore vášho účtu; rozsah e-shopov sa vyhodnocuje pri každej udalosti.
Tarifa Odchádzajúce webhooky Endpointov
Skúšobná 0
Začiatočník 0
Start áno 5
Rast áno 20
Pro áno 50
Na mieru podľa dohody podľa dohody

Počítajú sa nezmazané endpointy — zapnuté aj vypnuté. Zníženie tarify existujúce endpointy nezmaže; nový nepribudne, kým počet neklesne pod limit, a pri tarife bez webhookov sa udalosti prestanú posielať, kým sa tarifa nevráti.

Endpoint môžete použiť aj ako krok Odoslať webhook v Automatizáciách: správa odíde až po splnení podmienok pravidla, nie pri každej udalosti. Krok endpoint iba vyberá — adresa, tajomstvo a rozsah e-shopov zostávajú v registri.

Správa má typ automation.action (nedá sa odoberať priamo) a rovnakú obálku, podpis, opakovanie a denník ako ostatné udalosti. V data nesie automation.workflow_id, automation.run_id, automation.node_id, automation.source_event (udalosť, ktorá pravidlo prebudila) a identifikátory objednávky, zásielky alebo reklamačného prípadu; resource je entita behu. Detail si načítate cez REST API.

Ak prijímateľ neodpovie 30 pokusov za sebou alebo má endpoint viac než 5 000 čakajúcich doručení, MitoOps endpoint pozastaví a pošle vám upozornenie. Čakajúce doručenia zostávajú; po oprave prijímateľa endpoint zapnite a dobehnú. Denník doručení sa drží 30 dní.