Odlazni webhookovi
Provjereno
Ukratko
Odjeljak „Ukratko”Webhook je suprotnost REST-u i MCP-u: ne pitate Vi, nego se javlja MitoOps. Kada u računu nastane događaj na koji ste pretplaćeni, na Vašu adresu šaljemo POST s kratkom potpisanom omotnicom. Omotnica nosi identifikatore i stanja, a ne sadržaj narudžbe: detalje Vaš sustav učitava putem REST sučelja vlastitim ključem.
Pretplatama upravljate u aplikaciji: Postavke → API & MCP → Odlazni webhookovi. Dostupne su od tarife Start; potrebno je pravo Odlazni webhookovi (čitanje ili upravljanje).
Pretplata (endpoint)
Odjeljak „Pretplata (endpoint)”Endpoint ima naziv, adresu, popis događaja i opseg web trgovina. Pri otvaranju dobivate tajnu: prikazuje se jednom, a zatim više nikada; bilo kada je možete zamijeniti (rotacija), a stara odmah prestaje vrijediti.
- Adresa mora biti javna i putem
https://na standardnom portu. Adrese u unutarnju mrežu (lokalno računalo, privatni rasponi, metapodaci oblaka, VPN rasponi) odbijaju se pri spremanju i pri svakoj dostavi: naziv se ponovno razrješava, a veza se veže uz provjerene adrese. - Preusmjeravanja se ne slijede. Odgovor
3xxje neuspjeh. - Web trgovine: sve (i one koje se dodaju) ili odabrane. Događaj iz web trgovine izvan opsega ne šalje se.
- Probna dostava s gumba šalje događaj
pingistim putem kao stvarna: uključujući potpis i upis u dnevnik. - Endpoint se može isključiti (dostave koje čekaju se preskaču) i izbrisati (dnevnik ostaje).
Događaji
Odjeljak „Događaji”| Događaj | Kada | resource.type |
Polja u data |
|---|---|---|---|
order.created |
nova narudžba iz web trgovine | order |
order_code |
order.paid |
narudžba označena kao plaćena | order |
order_code |
order.status_changed |
promjena statusa narudžbe | order |
order_code, status_id, previous_status_id |
shipment.created |
pošiljka izrađena kod dostavne službe | shipment |
shipment_id, order_code, carrier_code, tracking_number |
shipment.status_changed |
promjena statusa pošiljke (dostavna služba ili osoblje) | shipment |
shipment_id, order_code, carrier_code, status, previous_status, tracking_number |
shipment.delivered |
pošiljka dostavljena; dodatno uz shipment.status_changed |
shipment |
kao iznad, status je DELIVERED |
inventory.stock_changed |
kretanje zalihe stavke | inventory_item |
item_id, sku, kind |
invoice.created |
izdan račun | invoice |
invoice_code, order_code |
claim.created |
otvorena reklamacija (od kupca ili osoblja) | claim |
claim_code, order_code |
claim.status_changed |
promjena stanja reklamacije | claim |
claim_code, order_code, status_id |
claim.closed |
reklamacija zatvorena | claim |
claim_code, order_code |
search_console.connection.changed |
promjena stanja veze Search Consolea (povezivanje, promjena stranice, gubitak pristupa, odspajanje) | search_console_property |
market, status, previous_status, property, previous_property, changed_at |
search_console.sync.completed |
sinkronizacija arhiva dodala je ili promijenila dane | search_console_property |
market, property, search_types, data_state, final_data_through, fresh_data_through, days_upserted, revised_dates, sync_version, synced_at |
search_console.sync.failed |
sinkronizacija arhiva nije uspjela | search_console_property |
market, property, error, error_code, last_successful_sync_at, retry_at |
product_content.changed |
MitoOps je u web trgovinu upisao promijenjeni opis, kratki opis ili SEO tekst proizvoda | product |
store_id, market, entity, entity_id, canonical_url, source, source_run_id, changed_fields, before_hash, after_hash, changed_at |
category_content.changed |
MitoOps je u web trgovinu upisao promijenjeni gornji ili donji opis ili SEO tekst kategorije | category |
kao kod product_content.changed |
ping |
probna dostava s gumba | webhook_endpoint |
message, endpoint |
Događaji potječu iz istog poslovnog sloja kao automatizacije: ono što pokreće automatizaciju, na to se može pretplatiti i webhookom. Povratne pošiljke (povrati) ne šalju se kao shipment.*: pripadaju reklamaciji.
Promjena tekstova proizvoda i kategorija
Odjeljak „Promjena tekstova proizvoda i kategorija”product_content.changed i category_content.changed nastaju jednom po upisu i web trgovini kada MitoOps u web trgovinu upiše tekst koji se stvarno promijenio — s kartice proizvoda, skupnog uređivanja, uvoza, zaslona kategorija, iz odobrenog prijedloga ili autonomnog upisa. Promjena cijene, zalihe ili šifre, kao ni ponovno spremanje istog teksta, ne izaziva događaj. Izmjene napravljene izravno u administraciji web trgovine ovaj događaj ne javlja.
entityjeproductilicategory;entity_id(iresource.id) je šifra proizvoda, odnosno ID kategorije u web trgovini — isti s kojima čitate tekstove putemproducts_content_geticategories_content_get.store_idje šifra web trgovine, ista kaostore.source:ui(osoba u aplikaciji),assistant(asistent u aplikaciji),mcp(prijedlog putem MCP-a koji je odobrila osoba),autonomous(prijedlog upisan u autonomnom načinu). Vrijednostrestje rezervirana — REST je danas samo za čitanje.source_run_id: ID prijedloga kod odobrenog i autonomnog upisa; kod ostalih upisa proizvoda ID serije upisa (Promjene proizvoda); kod kategorije spremljene izvan prijedloganull.changed_fieldsnavodi promijenjena polja: za proizvoddescription,shortDescription,metaTitle,metaDescription, za kategorijudescription,descriptionBottom,metaTitle,metaDescription.before_hashiafter_hashza svako od njih nose SHA-256 teksta u UTF-8 (vrijednost koja nedostaje = otisak praznog niza) — istu vrijednost koju pri čitanju vraća poljehash. Sam tekst omotnica ne nosi.- Nakon odobrenja prijedloga
after_hashje otisak onoga što je web trgovina nakon upisa stvarno spremila (WordPress na primjer uklanja blok<style>), a ne onoga što je predloženo. canonical_urlje javna adresa proizvoda ili kategorije ako je MitoOps zna; inačenull.
Što vaš ključ smije čitati i predlagati u određenoj web trgovini te hoće li se prijedlog upisati sam, provjerite unaprijed putem pravila sadržaja: GET /api/v1/product-content/policy?market=… ili MCP alatom products_content_policy (opseg product-content:read).
Omotnica
Odjeljak „Omotnica”Svaka dostava je JSON s verzijom omotnice. Novo polje može se dodati bez promjene verzije; promjena značenja polja je nova verzija.
{ "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_idje jedinstven za događaj. Ako su na isti događaj pretplaćena dva Vaša endpointa, dobivaju isti ID. Ponovljeni pokušaj nosi isti ID i isto tijelo.storeje kod web trgovine (market): isti koji koristi REST.tenantje identifikator Vašeg računa u MitoOps.
Zaglavlja i potpis
Odjeljak „Zaglavlja i potpis”Content-Type: application/jsonUser-Agent: MitoOps-Webhooks/1X-MitoOps-Event: shipment.deliveredX-MitoOps-Event-Id: 9b2f0c1e-6d3a-4c7e-9a2b-0f1e2d3c4b5aX-MitoOps-Timestamp: 1756888872X-MitoOps-Signature: v1=3f1a…c9e0X-MitoOps-Delivery: 184Potpis je HMAC-SHA256 s ključem = tajna endpointa nad nizom:
<X-MitoOps-Timestamp> + "." + <točno tijelo zahtjeva>Rezultat je heksadecimalan, a u zaglavlju stoji s prefiksom verzije v1=. Vremenska oznaka je unixovo vrijeme u sekundama.
Provjera na Vašoj strani
Odjeljak „Provjera na Vašoj strani”Provjeravajte nad sirovim tijelom zahtjeva (bajtovi onakvi kakvi su stigli), a ne nad ponovno serijaliziranim JSON-om: svaka promjena razmaka ili redoslijeda ključeva poništava potpis. Uspoređujte u konstantnom vremenu i odbijte poruke starije od 5 minuta.
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; // stara ili nedostajuća oznaka
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)Zaštita od ponovne reprodukcije
Odjeljak „Zaštita od ponovne reprodukcije”Potpis pokriva vremensku oznaku, pa presretnutu poruku nije moguće kasnije poslati s novim vremenom. Uz provjeru vremena čuvajte event_id posljednjih dostava i zanemarite duplikate: ponovljena dostava svojstvo je sustava, a ne greška.
Odgovor, ponavljanje i dnevnik
Odjeljak „Odgovor, ponavljanje i dnevnik”- Odgovorite
2xxunutar 10 sekundi. Tijelo odgovora se ne čita. Obradu koja traje dulje stavite u pozadinu i odgovorite odmah. - Drugi odgovor (
4xx,5xx), istek vremena ili greška veze = neuspjeh i ponavljanje s razmacima od 1, 5, 15, 60 i 240 minuta; ukupno šest pokušaja. Zatim je dostavaFAILEDi čeka ručno ponavljanje iz dnevnika. - Odgovor
3xxi adresa koja se prestala razrješavati na javnu mrežu neuspjesi su bez ponavljanja: sami se neće riješiti. - Dnevnik dostava u aplikaciji za svaki pokušaj prikazuje stanje, HTTP kod, vrijeme, broj pokušaja i događaj. Tijelo poruke u dnevniku se ne prikazuje.
| Stanje | Značenje |
|---|---|
PENDING |
čeka pokušaj ili sljedeće ponavljanje |
SENT |
primatelj je odgovorio 2xx |
FAILED |
pokušaji su iscrpljeni ili je greška trajna; može se ponoviti ručno |
SKIPPED |
endpoint je u međuvremenu isključen ili izbrisan |
Sigurnost
Odjeljak „Sigurnost”- Tajna se sprema šifrirano i nikada se ne zapisuje u logove ni u dnevnik. Prikazuje se jednom; rotacija radi i kada tarifa više ne uključuje webhookove: to je sigurnosna operacija.
- Bez osobnih podataka. Omotnica nosi identifikatore i stanja. Ime, adresa ni e-pošta kupca ne šalju se; tko ih treba, čita ih putem REST-a s vlastitim opsegom i revizijom.
- Samo HTTPS, samo javne adrese, bez preusmjeravanja. Provjera pri spremanju i pri svakoj dostavi štiti od usmjeravanja u unutarnju mrežu i od promjene DNS-a.
- Pretplatu otvara osoba, a ne ključ. Pristupni ključ za REST ni OAuth privola ne mogu otvoriti pretplatu: čitanje na zahtjev i trajni tok događaja prema van dva su različita ovlaštenja.
- Izolacija. Pretplate i dnevnik nalaze se u prostoru Vašeg računa; opseg web trgovina procjenjuje se pri svakom događaju.
Tarifa
Odjeljak „Tarifa”| Tarifa | Odlazni webhookovi | Endpointa |
|---|---|---|
| Probna | ne | 0 |
| Početnik | ne | 0 |
| Start | da | 5 |
| Rast | da | 20 |
| Pro | da | 50 |
| Po mjeri | prema dogovoru | prema dogovoru |
Broje se neizbrisani endpointi: uključeni i isključeni. Snižavanje tarife ne briše postojeće endpointe; novi se ne dodaje dok broj ne padne ispod ograničenja, a kod tarife bez webhookova događaji se prestaju slati dok se tarifa ne vrati.
Webhook iz automatizacije
Odjeljak „Webhook iz automatizacije”Endpoint možete koristiti i kao korak Poslati webhook u Automatizacijama: poruka odlazi tek nakon ispunjenja uvjeta pravila, a ne pri svakom događaju. Korak endpoint samo odabire: adresa, tajna i opseg web trgovina ostaju u registru.
Poruka ima vrstu automation.action (na nju se ne može izravno pretplatiti) i istu omotnicu, potpis, ponavljanje i dnevnik kao ostali događaji. U data nosi automation.workflow_id, automation.run_id, automation.node_id, automation.source_event (događaj koji je probudio pravilo) i identifikatore narudžbe, pošiljke ili reklamacijskog predmeta; resource je entitet izvođenja. Detalje učitavate putem REST API-ja.
Automatska suspenzija
Odjeljak „Automatska suspenzija”Ako primatelj ne odgovori na 30 uzastopnih pokušaja ili endpoint ima više od 5 000 dostava koje čekaju, MitoOps privremeno zaustavlja endpoint i šalje Vam upozorenje. Dostave koje čekaju ostaju; nakon popravka primatelja uključite endpoint i one će se dovršiti. Dnevnik dostava čuva se 30 dana.