# Tárolás és kiszállítás

Áruk betárolása, majd a tárolt tételek kiszállítása: konfiguráció → árajánlat → tárolás létrehozása → fizetés → még raktáron lévő tételek listázása → kiszállítás becslése → kiszállítás létrehozása → fizetés → követés → törlés.

Ez az útmutató kizárólag a következő műveleteket dokumentálja. Hajtsa végre őket sorrendben. A hitelesítés **ügyfél** fiókot használ.

Cserélje a `YOUR_HOST` és `ACCESS_TOKEN` értékeket a saját környezetének értékeire.

## 1. Belépés (ügyfél)

```bash
curl -X POST https://YOUR_HOST/api/v1/user/customer/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"your_password"}'
```

```
Authorization: Bearer ACCESS_TOKEN
```

A GraphQL ugyanazt a fejlécet használja a `POST /api/graphql` híváson.

**Ellenőrzés:** a belépés `access_token`-t ad. Későbbi hívás nélküle `401`.

## 2. Tárolási konfiguráció

**REST:** `GET /api/v1/customer/storage-orders/config` — [REST kézikönyv](/api/documentation#/paths/v1-customer-storage-orders-config/get)

```bash
curl https://YOUR_HOST/api/v1/customer/storage-orders/config \
  -H "Authorization: Bearer ACCESS_TOKEN"
```

**GraphQL:** `customerStorageOrderConfig` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerStorageOrderConfig))

**Ellenőrzés:** rögzített egy raktár-`id`-t, és ha a katalógus nem üres, egy csomagolás-`id`-t.

## 3. Tárolási árajánlat

**REST:** `POST /api/v1/customer/storage-orders/calculate-price`

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/storage-orders/calculate-price \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "warehouse_id": 7,
    "start_date": "2026-09-10",
    "end_date": "2026-10-10",
    "items": [{
      "qty": 1,
      "length": 30,
      "width": 20,
      "height": 15,
      "dimension_unit": 2,
      "weight": 2,
      "weight_unit": 2
    }]
  }'
```

**Ellenőrzés:** a `success` vagy a `result` true, és van ára. Hiányzó `warehouse_id` / dátumok: `400`.

## 4. A tárolási rendelés létrehozása

**REST:** `POST /api/v1/customer/storage-orders`

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/storage-orders \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dev-store-001" \
  -d '{
    "warehouse_id": 7,
    "start_date": "2026-09-10",
    "end_date": "2026-10-10",
    "items": [{
      "description": "Box A",
      "qty": 1,
      "length": 30,
      "width": 20,
      "height": 15,
      "dimension_unit": 2,
      "weight": 2,
      "weight_unit": 2,
      "value": 100
    }]
  }'
```

**Ellenőrzés:** a válasz tartalmazza a `data.id` értéket. Tárolja azt a tárolási rendelés azonosítót.

## 5. Tárolás fizetése

**REST:** `POST /api/v1/customer/storage-orders/{id}/pay`

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/storage-orders/1024/pay \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Opcionális: először `GET /api/v1/customer/storage-orders/{id}/payment-info`.

**REST:** `GET /api/v1/customer/storage-orders/{id}` — [REST kézikönyv](/api/documentation#/paths/v1-customer-storage-orders-id/get)

**GraphQL:** `customerStorageOrderShow` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerStorageOrderShow))

**Ellenőrzés:** a tárolási rendelés ki van fizetve / megerősítve. A `402` azt jelenti: töltse fel a tárcát, majd próbálja újra.

Az alábbi kiszállítás csak akkor működik, ha a csomagokat **átvették** a raktárban. Tesztnél várja meg, amíg a személyzet (vagy egy tesztátvétel) beérkezettnek jelöli őket, majd folytassa.

## 6. Még raktáron lévő tételek listázása

**REST:** `GET /api/v1/customer/shipout-orders/available-items` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-available-items/get)

```bash
curl "https://YOUR_HOST/api/v1/customer/shipout-orders/available-items?warehouse_id=7" \
  -H "Authorization: Bearer ACCESS_TOKEN"
```

**GraphQL:** `customerShipoutAvailableItems` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerShipoutAvailableItems))

**Ellenőrzés:** rögzített egy vagy több `storage_package_ids` értéket (példa: `5001`). Üres lista azt jelenti, hogy még semmi nincs átvéve — ne hozzon létre kiszállítást. A `403` azt jelenti, hogy a kiszállítás le van tiltva ennél az ügyfélnél.

## 7. A kiszállítás becslése és létrehozása

**REST:** `GET /api/v1/customer/shipout-orders/services?warehouse_id=7` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-services/get)

Rögzítsen egy `service_code` értéket.

**REST:** `POST /api/v1/customer/shipout-orders/services/{serviceCode}/estimate` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-services-serviceCode--estimate/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/shipout-orders/services/intl_express/estimate \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "warehouse_id": 7,
    "delivery_postcode": "M5V2H1",
    "delivery_country": "CA",
    "packages": [{
      "weight": 2.5,
      "length": 30,
      "width": 20,
      "height": 15,
      "weight_unit": 2,
      "dimension_unit": 2
    }]
  }'
```

**REST:** `POST /api/v1/customer/shipout-orders/services/{serviceCode}/orders` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-services-serviceCode--orders/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/shipout-orders/services/intl_express/orders \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dev-shipout-001" \
  -d '{
    "warehouse_id": 7,
    "storage_package_ids": [5001],
    "delivery_name": "Jane Recipient",
    "delivery_telephone": "5555555555",
    "delivery_email": "jane@example.com",
    "delivery_address_1": "123 King St W",
    "delivery_city": "Toronto",
    "delivery_province": "ON",
    "delivery_country": "CA",
    "delivery_postcode": "M5V2H1"
  }'
```

**GraphQL:** `customerCreateShipoutOrder` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerCreateShipoutOrder))

**Ellenőrzés:** a válasz tartalmaz kiszállítás-`id`-t. A kiválasztott tárolási csomagok ehhez a kéréshez vannak zárolva.

## 8. Kiszállítás fizetése, követés, események

**REST:** `POST /api/v1/customer/shipout-orders/{id}/pay` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-id--pay/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/shipout-orders/8001/pay \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**GraphQL:** `customerPayShipout` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerPayShipout))

**REST:** `GET /api/v1/customer/shipout-orders/{id}` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-id/get)

Ha van követési szám:

```bash
curl https://YOUR_HOST/api/v1/tracking/SR123456789012
```

[REST kézikönyv](/api/documentation#/operations/getPublicTracking) · [GraphQL kézikönyv](/api/graphql/documentation#/tracking/trackingPublic)

**REST:** `PUT /api/v1/webhook-settings` — [REST kézikönyv](/api/documentation#/paths/v1-webhook-settings/put)

**GraphQL:** `webhookSettingsUpdate` ([GraphQL kézikönyv](/api/graphql/documentation#/webhooks/webhookSettingsUpdate)).

A **v2** ellenőrzés: `HMAC_SHA256(timestamp + "." + raw_body, secret)` a `X-Webhook-Signature-V2` ellen. Deduplikáljon `X-Webhook-Event-Id` szerint. Válaszoljon **2xx-szel 3 másodpercen belül**.

```php
$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE_V2'] ?? '';
$expected = hash_hmac('sha256', $ts . '.' . $raw, $sharedSecret);
if (!hash_equals($expected, $sig)) {
    http_response_code(401);
    exit;
}
```

**Ellenőrzés:** a fizetés összeget rögzít (vagy `402` / `422` egyértelmű indokkal). A nyilvános követés megtalálja a küldeményt, amint van szám.

## 9. Tesztkiszállítás törlése

**REST:** `POST /api/v1/customer/shipout-orders/{id}/cancel` — [REST kézikönyv](/api/documentation#/paths/v1-customer-shipout-orders-id--cancel/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/shipout-orders/8001/cancel \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**GraphQL:** `customerCancelShipout` ([GraphQL kézikönyv](/api/graphql/documentation#/customer/customerCancelShipout))

Ez feloldja a tárolási csomag zárolását. Magát a tárolást a `POST /api/v1/customer/storage-orders/{id}/cancel` hívással törli, amíg még engedélyezett.

**Ellenőrzés:** a `422` azt jelenti, hogy ez az állapot nem törölhető. Sikeres kiszállítás-törlés után a 6. lépés újra listázza a csomagokat.

## Teszlista

- [ ] A tárolási konfiguráció raktár-`id`-t ad.
- [ ] A tárolási árajánlat árat ad.
- [ ] A tárolás létrehozása `data.id` értéket ad.
- [ ] A tárolás fizetése sikerül, **vagy** megerősítette, hogy a tárcát fel kell tölteni.
- [ ] Az elérhető tételek listázzák az átvett csomagokat (`storage_package_ids`).
- [ ] A kiszállítás becslése árat vagy `has_items_needing_quote` értéket ad.
- [ ] A kiszállítás létrehozása `id`-t ad, és zárolja azokat a csomagokat.
- [ ] A kiszállítás fizetése sikerül (vagy a `402` / `422` kódok értelmezettek).
- [ ] A nyilvános követés megtalálja a küldeményt, amint van követési szám.
- [ ] A kiszállítás törlése feloldja a csomagokat, **vagy** ez az állapot nem törölhető.
