Files
Funnel_Wiki/docs/integrace-eshop.md
2026-04-22 13:05:30 +02:00

247 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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: <vas-site-key>
```
nebo
```
POST https://tracking.domena.cz/api/eshop/cart?site_key=<vas-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: <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: <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`)