From 75d96f58ec4a43f062179d6891a9df314342bfd7 Mon Sep 17 00:00:00 2001 From: michal Date: Wed, 22 Apr 2026 13:05:30 +0200 Subject: [PATCH] update --- docs/integrace-eshop.md | 246 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 docs/integrace-eshop.md diff --git a/docs/integrace-eshop.md b/docs/integrace-eshop.md new file mode 100644 index 0000000..17d4a8c --- /dev/null +++ b/docs/integrace-eshop.md @@ -0,0 +1,246 @@ +# Požadavky na integraci eshopu – Tracking API + +Dokument popisuje, jak má eshop posílat data o košících a objednávkách. +Integrace je **serverová** – eshop posílá data přímo z backendu podle e-mailu zákazníka, žádné browser-tracking cookies nejsou potřeba. + +--- + +## 1. Autentizace + +Každý požadavek musí obsahovat **Site Key** – buď jako HTTP hlavičku, nebo jako query parametr: + +``` +X-Site-Key: +``` +nebo + +``` +POST https://tracking.domena.cz/api/eshop/cart?site_key= +``` + +Site Key vám bude přiděleno naší stranou. + +--- + +## 2. Endpoint: Stav košíku + +Volejte **při každé změně košíku** (přidání, odebrání, změna množství). +Párování košíku probíhá automaticky podle e-mailu zákazníka. + +``` +POST /api/eshop/cart +Content-Type: application/json +X-Site-Key: +``` + +### Tělo požadavku + +```json +{ + "email": "zakaznik@example.cz", + "currency": "CZK", + "total_no_tax": 198.00, + "cart_id": null, + "occurred_at": "2026-04-22T10:00:00+02:00", + "items": [ + { + "code": "PROD-001", + "name": "Název produktu", + "qty": 2, + "unit_no_tax": 99.00, + "total_no_tax": 198.00, + "url": "https://eshop.cz/produkt/nazev" + } + ] +} +``` + +### Popis polí + +| Pole | Typ | Povinné | Popis | +|------|-----|---------|-------| +| `email` | string | ✅ | E-mail zákazníka – slouží k párování košíku | +| `currency` | string | ✅ | ISO kód měny, např. `"CZK"` | +| `total_no_tax` | float | ne | Celková suma košíku bez DPH | +| `cart_id` | int\|null | ne | ID košíku z předchozí odpovědi; při prvním volání vynechejte nebo pošlete `null` | +| `occurred_at` | datetime | ne | ISO 8601 čas události | +| `items` | array | ✅ | Pole položek (prázdné pole = prázdný košík) | +| `items[].code` | string | ✅ | SKU / kód produktu | +| `items[].name` | string | ne | Název produktu | +| `items[].qty` | int | ✅ | Počet kusů | +| `items[].unit_no_tax` | float | ne | Cena za kus bez DPH | +| `items[].total_no_tax` | float | ne | Celková cena za řádek bez DPH | +| `items[].url` | string | ne | URL produktu | + +### Logika párování košíku + +1. Eshop pošle e-mail → systém najde nebo vytvoří kontakt. +2. Systém hledá **poslední otevřený košík** pro daný kontakt. +3. Pokud obsah košíku je stejný jako naposledy, jen obnoví `last_seen_at` (žádný duplikát). +4. Pokud se obsah liší, aktualizuje košík a zapíše nový event. +5. `cart_id` z odpovědi doporučujeme ukládat a posílat zpět – urychlí párování. + +### Odpověď + +```json +{ + "ok": true, + "cart_id": 42, + "status": "open", + "changed": true +} +``` + +> ⚠️ **`cart_id` z odpovědi si uložte** a posílejte ho v dalších voláních. Pokud ho nepošlete, systém dohledá košík sám podle e-mailu, ale s `cart_id` je to rychlejší a spolehlivější. + +--- + +## 3. Endpoint: Dokončení objednávky + +Volejte **jednorázově** při úspěšném dokončení objednávky (stránka "Děkujeme za objednávku" nebo webhook ze systému objednávek). + +``` +POST /api/eshop/order +Content-Type: application/json +X-Site-Key: +``` + +### Tělo požadavku + +```json +{ + "email": "zakaznik@example.cz", + "cart_id": 42, + "order_id": "ORD-2026-0042", + "total_no_tax": 198.00, + "currency": "CZK", + "occurred_at": "2026-04-22T10:05:00+02:00", + "items": [ + { + "code": "PROD-001", + "name": "Název produktu", + "qty": 2, + "unit_no_tax": 99.00, + "total_no_tax": 198.00 + } + ], + "checkout": { + "shipping_no_tax": 89.00, + "shipping_label": "PPL", + "cod_fee_no_tax": 29.00 + } +} +``` + +### Popis polí + +| Pole | Typ | Povinné | Popis | +|------|-----|---------|-------| +| `email` | string | ✅ | E-mail zákazníka | +| `cart_id` | int | ne | ID košíku z předchozích volání (doporučeno) | +| `order_id` | string | ne | ID objednávky ve vašem systému | +| `total_no_tax` | float | ne | Celková hodnota objednávky bez DPH | +| `currency` | string | ne | Měna, např. `"CZK"` | +| `items` | array | ne | Stejný formát jako u `/eshop/cart` | +| `checkout.shipping_no_tax` | float | ne | Cena dopravy bez DPH | +| `checkout.shipping_label` | string | ne | Název dopravce (PPL, Zásilkovna...) | +| `checkout.cod_fee_no_tax` | float | ne | Příplatek za dobírku bez DPH | + +### Logika párování objednávky + +1. Systém najde kontakt podle e-mailu. +2. Hledá košík podle `cart_id` (pokud přišel), jinak poslední otevřený košík pro daný kontakt. +3. Pokud žádný košík nenajde, vrátí chybu `cart_not_found` (404). +4. Košík označí jako `converted` a uloží data objednávky. + +### Odpověď + +```json +{ + "ok": true, + "cart_id": 42, + "order_id": "ORD-2026-0042", + "status": "converted" +} +``` + +--- + +## 4. Chybové stavy + +| HTTP kód | Chyba | Řešení | +|----------|-------|--------| +| 401 | Missing/invalid site key | Zkontrolujte X-Site-Key | +| 422 | Chybí povinné pole | Viz popis polí výše | +| 404 | `cart_not_found` | Zákazník neměl otevřený košík; pošlete nejdřív `/eshop/cart` | +| 500 | Server error | Opakujte požadavek, dejte nám vědět | + +--- + +## 5. Doporučené pořadí volání + +``` +Zákazník přidá produkt do košíku + └─ POST /api/eshop/cart {email, items, currency, ...} + └─ uložit cart_id z odpovědi + +Zákazník změní množství / přidá další produkt + └─ POST /api/eshop/cart {email, cart_id, items, ...} + (pokud se obsah nezměnil, systém jen obnoví čas – žádný duplikát) + +Zákazník dokončí objednávku + └─ POST /api/eshop/order {email, cart_id, order_id, ...} +``` + +--- + +## 6. PHP příklad + +```php +// Při změně košíku +$response = Http::withHeaders(['X-Site-Key' => config('tracking.site_key')]) + ->post('https://tracking.domena.cz/api/eshop/cart', [ + 'email' => $customer->email, + 'currency' => 'CZK', + 'total_no_tax' => $cart->totalNoTax(), + 'cart_id' => session('ft_cart_id'), // null při prvním volání + 'items' => $cart->items->map(fn($item) => [ + 'code' => $item->sku, + 'name' => $item->name, + 'qty' => $item->qty, + 'unit_no_tax' => $item->unitPriceNoTax, + 'total_no_tax' => $item->totalNoTax, + 'url' => $item->url, + ])->toArray(), + ]); + +// Uložit cart_id pro příští volání +if ($response->successful()) { + session(['ft_cart_id' => $response->json('cart_id')]); +} + +// Při dokončení objednávky +Http::withHeaders(['X-Site-Key' => config('tracking.site_key')]) + ->post('https://tracking.domena.cz/api/eshop/order', [ + 'email' => $customer->email, + 'cart_id' => session('ft_cart_id'), + 'order_id' => $order->id, + 'total_no_tax' => $order->totalNoTax(), + 'currency' => 'CZK', + 'checkout' => [ + 'shipping_no_tax' => $order->shippingNoTax, + 'shipping_label' => $order->shippingLabel, + 'cod_fee_no_tax' => $order->codFeeNoTax, + ], + ]); +``` + +--- + +## 7. Technické poznámky + +- Všechna data v **UTF-8**, `Content-Type: application/json` +- `occurred_at` v ISO 8601 formátu, ideálně s časovou zónou +- Ceny jako **float bez DPH** – pokud nemáte ceny bez DPH, uveďte ceny s DPH a poznamenejte to +- Pokud zákazník nakupuje bez přihlášení (guest checkout) a e-mail je znám až při dokončení objednávky, pošlete `/eshop/cart` s e-mailem hned jak ho zadá do checkoutu +- Volání `/eshop/cart` s prázdným `items: []` správně uzavře košík (status `empty`)