# Szállítási szolgáltatások

Használja a logisztikai cég saját szállítási szolgáltatásait: szolgáltatások listázása → egy szolgáltatás konfigurációjának betöltése → becslés → rendelés létrehozása → fizetés → visszaolvasás → követés → tesztrendelés törlése.

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"}'
```

Az `access_token` így használandó:

```
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. Szolgáltatások listázása

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

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

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

Minden sor tartalmazza a `service_code`, `name`, `offer_pickup`, `allow_warehouse_delivery` mezőket. Üres lista azt jelenti, hogy ehhez az ügyfélhez nincs hozzárendelve szolgáltatás.

**Ellenőrzés:** rögzített egy `service_code` értéket (az alábbi példa: `intl_express`).

## 3. A szolgáltatás konfigurációjának betöltése

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

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

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

**Ellenőrzés:** van legalább egy raktár-`id`, ha a szolgáltatás enged raktári leadást. A `403` azt jelenti, hogy ez az ügyfél nem használhatja azt a szolgáltatást.

## 4. Becslés

**REST:** `POST /api/v1/customer/shipping-orders/services/{serviceCode}/estimate-price`

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

`origin_type`: `warehouse` (leadás raktárban) vagy `pickup` (a cég felveszi). Egyezzen azzal, amit a 3. lépés szerint a szolgáltatás enged.

**Ellenőrzés:** a `result` true, és van ára (vagy „árajánlat szükséges” jelző kézi árazáshoz). Még ne hozzon létre, ha a célt/csomagot elutasították.

## 5. A rendelés létrehozása

**REST:** `POST /api/v1/customer/shipping-orders/services/{serviceCode}/orders`

Küldjön `Idempotency-Key`-t.

```bash
curl -X POST https://YOUR_HOST/api/v1/customer/shipping-orders/services/intl_express/orders \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dev-ship-001" \
  -d '{
    "origin_type": "warehouse",
    "warehouse_id": 7,
    "reference": "DEV-SHIP-001",
    "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",
    "package": [{
      "weight": 2,
      "length": 30,
      "width": 20,
      "height": 15,
      "weight_unit": 2,
      "dimension_unit": 2,
      "quantity": 1
    }]
  }'
```

**Ellenőrzés:** a válasz tartalmaz rendelés-`id`-t. Tárolja az `id`, `tracking_number` / `reference_number` értékeket, ha vannak.

## 6. Fizetés

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

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

Opcionális: először `GET /api/v1/customer/shipping-orders/{id}/payment-info`. A `402` azt jelenti, hogy a tárca nem fedezi az összeget — töltse fel, majd próbálja újra.

**Ellenőrzés:** a rendelés már nem fizetendő, vagy a `remaining_balance` `0`.

## 7. Rendelés lekérdezése és követés

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

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

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

Ha a rendelésen van `tracking_number`, nyilvános követés (token nélkül):

```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)

**Ellenőrzés:** a részlet ennek az ügyfélnek a rendelése. A nyilvános követés megtalálja, amint van szám.

## 8. Eseményértesítések beállítása

| Beállítás | Esemény | Mikor |
|---|---|---|
| `order_create_webhook_url` | `order.created` | `id` és követési számok mentése |
| `tracking_event_webhook_url` | `tracking.event` | Idővonal |
| `order_status_change_webhook_url` | `order.status_change` | Állapot a rendszerében |

**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 a nyers törzsön: `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:** egy teszt létrehozása `order.created` eseményt ad azzal az `id`-vel.

## 9. Tesztrendelés törlése

**REST:** `POST /api/v1/customer/shipping-orders/{id}/cancel`

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

**Ellenőrzés:** a második törlés biztonságos, vagy az API jelzi, hogy a rendelés már törölve van. A `422` azt jelenti, hogy ez az állapot nem törölhető.

## Teszlista

Használjon teszt `reference` értéket, pl. `DEV-SHIP-001`:

- [ ] A szolgáltatáslista nem üres; rögzített egy `service_code` értéket.
- [ ] A konfiguráció raktárakat / csomagolást ad ahhoz a szolgáltatáshoz.
- [ ] A becslés árat ad (vagy egyértelmű árajánlat-szükséges jelzőt).
- [ ] A létrehozás `id`-t ad; ugyanaz az `Idempotency-Key` nem hoz létre második rendelést.
- [ ] A fizetés sikerül, **vagy** megerősítette, hogy a tárcát fel kell tölteni (`402`).
- [ ] A részlet ennek az ügyfélnek a rendelését mutatja.
- [ ] A nyilvános követés megtalálja a küldeményt, amint van követési szám.
- [ ] A törlés sikerül, **vagy** megerősítette, hogy ez az állapot nem törölhető.
