Preskoči na vsebino

Odhodni webhooki

Preverjeno

Webhook je nasprotje REST in MCP: ne sprašujete vi, oglasi se MitoOps. Ko v računu nastane dogodek, na katerega ste naročeni, na vaš naslov pošljemo POST s kratko podpisano ovojnico. Ovojnica nosi identifikatorje in stanja, ne vsebine naročila; podrobnosti vaš sistem naloži prek vmesnika REST z lastnim ključem.

Naročnine upravljate v aplikaciji: Nastavitve → API & MCP → Odhodni webhooki. Na voljo so od paketa Start; potrebna je pravica Odhodni webhooki (branje ali upravljanje).

Naročnina (končna točka)

Razdelek »Naročnina (končna točka)«

Končna točka (endpoint) ima ime, naslov, seznam dogodkov in obseg spletnih trgovin. Pri ustvarjanju prejmete skrivnost: prikaže se enkrat, potem nikoli več; kadarkoli jo lahko zamenjate (rotacija), stara pa takoj preneha veljati.

  • Naslov mora biti javen in prek https:// na standardnih vratih. Naslovi v notranje omrežje (lokalni računalnik, zasebni obsegi, metapodatki oblaka, obsegi VPN) se zavrnejo ob shranjevanju in pri vsaki dostavi: ime se razreši znova, povezava pa se veže na preverjene naslove.
  • Preusmeritvam se ne sledi. Odgovor 3xx je neuspeh.
  • Spletne trgovine: vse (tudi tiste, ki bodo dodane pozneje) ali izbrane. Dogodek iz spletne trgovine zunaj obsega se ne pošlje.
  • Preizkusna dostava z gumbom pošlje dogodek ping po isti poti kot pravi dogodek, vključno s podpisom in zapisom v dnevnik.
  • Končno točko je mogoče izklopiti (čakajoče dostave se preskočijo) in izbrisati (dnevnik ostane).
Dogodek Kdaj resource.type Polja v data
order.created novo naročilo iz spletne trgovine order order_code
order.paid naročilo, označeno kot plačano order order_code
order.status_changed sprememba stanja naročila order order_code, status_id, previous_status_id
shipment.created pošiljka, ustvarjena pri prevozniku shipment shipment_id, order_code, carrier_code, tracking_number
shipment.status_changed sprememba stanja pošiljke (prevoznik ali osebje) shipment shipment_id, order_code, carrier_code, status, previous_status, tracking_number
shipment.delivered pošiljka dostavljena; dodatno k shipment.status_changed shipment kot zgoraj, status je DELIVERED
inventory.stock_changed premik zaloge postavke inventory_item item_id, sku, kind
invoice.created izdan račun invoice invoice_code, order_code
claim.created ustvarjena reklamacija (s strani kupca ali osebja) claim claim_code, order_code
claim.status_changed sprememba stanja reklamacije claim claim_code, order_code, status_id
claim.closed reklamacija zaključena claim claim_code, order_code
search_console.connection.changed sprememba stanja povezave Search Console (povezava, sprememba spletnega mesta, izguba dostopa, prekinitev) search_console_property market, status, previous_status, property, previous_property, changed_at
search_console.sync.completed sinhronizacija arhiva je dodala ali spremenila dneve 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 sinhronizacija arhiva ni uspela search_console_property market, property, error, error_code, last_successful_sync_at, retry_at
product_content.changed MitoOps je v spletno trgovino zapisal spremenjen opis, kratek opis ali SEO besedilo izdelka 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 v spletno trgovino zapisal spremenjen zgornji ali spodnji opis ali SEO besedilo kategorije category kot pri product_content.changed
ping preizkusna dostava z gumbom webhook_endpoint message, endpoint

Dogodki izhajajo iz iste poslovne plasti kot avtomatizacije: kar sproži avtomatizacijo, lahko prejemate tudi prek webhooka. Povratne pošiljke (vračila) se ne pošiljajo kot shipment.*, ker spadajo k reklamaciji.

Sprememba besedil izdelkov in kategorij

Razdelek »Sprememba besedil izdelkov in kategorij«

product_content.changed in category_content.changed nastaneta enkrat na zapis in spletno trgovino, ko MitoOps v spletno trgovino zapiše besedilo, ki se je dejansko spremenilo — iz kartice izdelka, množičnega urejanja, uvoza, zaslona kategorij, iz odobrenega predloga ali iz samodejnega zapisa. Sprememba cene, zaloge ali kode ter ponovno shranjevanje istega besedila dogodka ne sprožijo. Sprememb, narejenih neposredno v administraciji spletne trgovine, ta dogodek ne sporoča.

  • entity je product ali category; entity_id (in resource.id) je koda izdelka oziroma ID kategorije v spletni trgovini — enaka, s katerima berete besedila prek products_content_get in categories_content_get. store_id je koda spletne trgovine, enaka kot store.
  • source: ui (oseba v aplikaciji), assistant (pomočnik v aplikaciji), mcp (predlog prek MCP, ki ga je odobrila oseba), autonomous (predlog, zapisan v samodejnem načinu). Vrednost rest je rezervirana — REST je danes samo za branje.
  • source_run_id: ID predloga pri odobrenem in samodejnem zapisu; pri ostalih zapisih izdelka ID paketa zapisa (Spremembe izdelkov); pri kategoriji, shranjeni zunaj predloga, null.
  • changed_fields našteje spremenjena polja: pri izdelku description, shortDescription, metaTitle, metaDescription, pri kategoriji description, descriptionBottom, metaTitle, metaDescription. before_hash in after_hash za vsako od njih nosita SHA-256 besedila v UTF-8 (manjkajoča vrednost = prstni odtis praznega niza) — isto vrednost, ki jo pri branju vrne polje hash. Samega besedila ovojnica ne nosi.
  • Po odobritvi predloga je after_hash prstni odtis tega, kar je spletna trgovina po zapisu dejansko shranila (WordPress na primer odstrani blok <style>), ne tega, kar je bilo predlagano.
  • canonical_url je javni naslov izdelka ali kategorije, če ga MitoOps pozna; sicer null.

Kaj sme vaš ključ v določeni spletni trgovini brati in predlagati ter ali se bo predlog zapisal sam, preverite vnaprej s pravili vsebine: GET /api/v1/product-content/policy?market=… ali z orodjem MCP products_content_policy (obseg product-content:read).

Vsaka dostava je JSON z različico ovojnice. Novo polje lahko pribude brez spremembe različice; sprememba pomena polja pomeni novo različico.

{
"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 edinstven za dogodek. Če sta na isti dogodek naročeni dve vaši končni točki, prejmeta isti ID. Ponovni poskus nosi isti ID in isto telo.
  • store je koda spletne trgovine (market), ista, kot jo uporablja REST.
  • tenant je identifikator vašega računa 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 s ključem, ki je skrivnost končne točke, nad nizom:

<X-MitoOps-Timestamp> + "." + <natančno telo zahteve>

Rezultat je šestnajstiški in je v glavi s predpono različice v1=. Časovna oznaka je čas Unix v sekundah.

Preverjanje na vaši strani

Razdelek »Preverjanje na vaši strani«

Preverjajte nad surovim telesom zahteve (bajti, kot so prispeli), ne nad ponovno serializiranim JSON: vsaka sprememba presledka ali vrstnega reda ključev podpis razveljavi. Primerjajte v konstantnem času in zavrnite sporočila, starejša od 5 minut.

import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyMitoOpsWebhook({ secret, headers, rawBody, now = Math.floor(Date.now() / 1000) }) {
const ts = Number(headers['x-mitoops-timestamp']);
if (!Number.isFinite(ts) || Math.abs(now - ts) > 300) return false; // stara ali manjkajoča časovna oznaka
const received = String(headers['x-mitoops-signature'] || '')
.split(',').map((s) => s.trim()).find((s) => s.startsWith('v1='));
if (!received) return false;
const expected = createHmac('sha256', secret)
.update(String(ts) + '.').update(rawBody).digest('hex');
const a = Buffer.from(received.slice(3), 'hex');
const b = Buffer.from(expected, 'hex');
return a.length === b.length && timingSafeEqual(a, b);
}
import hmac, hashlib, time
def verify_mitoops_webhook(secret: str, headers: dict, raw_body: bytes) -> bool:
try:
ts = int(headers["X-MitoOps-Timestamp"])
except (KeyError, ValueError):
return False
if abs(int(time.time()) - ts) > 300:
return False
sig = next((s.strip() for s in headers.get("X-MitoOps-Signature", "").split(",") if s.strip().startswith("v1=")), None)
if not sig:
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(sig[3:], expected)

Zaščita pred ponovnim predvajanjem

Razdelek »Zaščita pred ponovnim predvajanjem«

Podpis zajema časovno oznako, zato prestreženega sporočila ni mogoče pozneje poslati z novim časom. Poleg preverjanja časa hranite event_id zadnjih dostav in podvojene dostave prezrite: ponovljena dostava je lastnost sistema, ne napaka.

Odgovor, ponavljanje in dnevnik

Razdelek »Odgovor, ponavljanje in dnevnik«
  • Odgovorite z 2xx v 10 sekundah. Telo odgovora se ne bere. Obdelavo, ki traja dlje, uvrstite v ozadje in odgovorite takoj.
  • Drugačen odgovor (4xx, 5xx), potek časa ali napaka povezave pomeni neuspeh in ponovitev z zamiki 1, 5, 15, 60 in 240 minut; skupaj šest poskusov. Nato je dostava FAILED in čaka na ročno ponovitev iz dnevnika.
  • Odgovor 3xx in naslov, ki se ne razreši več v javno omrežje, sta neuspeha brez ponovitve, ker se sama ne odpravita.
  • Dnevnik dostav v aplikaciji za vsak poskus prikazuje stanje, kodo HTTP, čas, število poskusov in dogodek. Telo sporočila se v dnevniku ne prikazuje.
Stanje Pomen
PENDING čaka na poskus ali na naslednjo ponovitev
SENT prejemnik je odgovoril z 2xx
FAILED poskusi so izčrpani ali gre za trajno napako; mogoče je ročno ponoviti
SKIPPED končna točka je bila medtem izklopljena ali izbrisana
  • Skrivnost se shrani šifrirana in se nikoli ne zapiše v dnevnike niti v dnevnik dostav. Prikaže se enkrat; rotacija deluje tudi takrat, ko paket webhookov ne vključuje več, saj gre za varnostno operacijo.
  • Brez osebnih podatkov. Ovojnica nosi identifikatorje in stanja. Ime, naslov in e-pošta kupca se ne pošiljajo; kdor jih potrebuje, jih bere prek REST z lastnim obsegom in revizijsko sledjo.
  • Samo HTTPS, samo javni naslovi, brez preusmeritev. Preverjanje ob shranjevanju in pri vsaki dostavi ščiti pred usmerjanjem v notranje omrežje in pred spremembo DNS.
  • Naročnino ustvari oseba, ne ključ. Naročnine ne more ustvariti niti dostopni ključ za REST niti soglasje OAuth: branje na zahtevo in stalen tok dogodkov navzven sta dve različni pravici.
  • Izolacija. Naročnine in dnevnik so v prostoru vašega računa; obseg spletnih trgovin se preverja pri vsakem dogodku.
Paket Odhodni webhooki Končne točke
Preizkusna različica - 0
Začetnik - 0
Start da 5
Rast da 20
Pro da 50
Po meri po dogovoru po dogovoru

Štejejo se neizbrisane končne točke, vklopljene in izklopljene. Znižanje paketa obstoječih končnih točk ne izbriše; nove ni mogoče dodati, dokler število ne pade pod omejitev, v paketu brez webhookov pa se dogodki prenehajo pošiljati, dokler se paket ne povrne.

Končno točko lahko uporabite tudi kot korak Poslati webhook v Avtomatizacijah: sporočilo odide šele, ko so izpolnjeni pogoji pravila, ne pri vsakem dogodku. Korak končno točko samo izbere; naslov, skrivnost in obseg spletnih trgovin ostanejo v registru.

Sporočilo ima vrsto automation.action (nanj se ni mogoče naročiti neposredno) ter enako ovojnico, podpis, ponavljanje in dnevnik kot ostali dogodki. V data nosi automation.workflow_id, automation.run_id, automation.node_id, automation.source_event (dogodek, ki je prebudil pravilo) in identifikatorje naročila, pošiljke ali reklamacijskega primera; resource je entiteta izvajanja. Podrobnosti naložite prek REST API.

Če prejemnik ne odgovori 30 poskusov zapored ali ima končna točka več kot 5.000 čakajočih dostav, MitoOps končno točko začasno ustavi in vam pošlje obvestilo. Čakajoče dostave ostanejo; ko prejemnika popravite, končno točko vklopite in dostave se nadoknadijo. Dnevnik dostav se hrani 30 dni.