# Fuvarozói címkék

Fuvarozói küldemény vásárlása: módok listázása → árajánlat → címke létrehozása → PDF letöltése → követés → események fogadása → törlés (vagy a nap zárása).

Ez az útmutató kizárólag a következő műveleteket dokumentálja. Hajtsa végre őket sorrendben.

Cserélje a `YOUR_HOST`, `ACCESS_TOKEN` és `shipping_method` értékeket a sajátjaira. A módazonosítók fiókonként különböznek — soha ne kódolja be őket.

## 1. Belépés

```bash
curl -X POST https://YOUR_HOST/api/v1/user/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.

[REST kézikönyv](/api/documentation#/paths/v1-user-login/post) · [GraphQL kézikönyv](/api/graphql/documentation#/user/userLogin)

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

## 2. Szállítási módok listázása

**REST:** `POST /api/v1/labelservice/getShippingMethodList` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-getShippingMethodList/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/getShippingMethodList \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"detail": true}'
```

Minden sor tartalmazza:

| Mező | Használat |
|---|---|
| `id` | `shipping_method` minden későbbi hívásban |
| `name` | Megjelenített név |
| `unique_identifier` | Stabil kód |
| `options.signature_option` | Aláírás elérhető |
| `options.insurance_option` | Biztosítás elérhető |
| `options.multi_package` | Több mint egy darab |

**GraphQL:** `labelserviceGetShippingMethodList` ([GraphQL kézikönyv](/api/graphql/documentation#/labelservice/labelserviceGetShippingMethodList)) (JSON skalár).

**Ellenőrzés:** a lista nem üres. Kiválasztott egy `id`-t, és tudja, hogy az a mód enged-e aláírást, biztosítást és több csomagot. Üres lista azt jelenti, hogy a fiókon nincs engedélyezett mód.

## 3. Árajánlat

Próbafutás. A fuvarozótól árat kérünk; semmi sem foglalódik. A törzs ugyanolyan alakú, mint a létrehozáskor. A `shipping_method` kötelező.

**REST:** `POST /api/v1/labelservice/rate` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-rate/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/rate \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "shipping_method": 59,
    "name": "Jane Recipient",
    "telephone": "5555555555",
    "email": "jane@example.com",
    "address_1": "6701 RUE HADLEY",
    "city": "Montreal",
    "province": "QC",
    "postcode": "H4E3R3",
    "country": "CA",
    "weight": 1,
    "length": 30,
    "width": 20,
    "height": 10,
    "dimension_unit": 2,
    "weight_unit": 2,
    "signature_option": 0,
    "insurance_option": 0,
    "package_type": "parcel",
    "ref": "DEV-LABEL-001",
    "sender_name": "Acme Warehouse",
    "sender_telephone": "5555555555",
    "sender_address_1": "2667 boul des sources",
    "sender_city": "Pointe-Claire",
    "sender_province": "QC",
    "sender_postcode": "H9S2H9",
    "sender_country": "CA"
  }'
```

`weight_unit`: `1` g, `2` kg, `3` oz, `4` lb. `dimension_unit`: `1` mm, `2` cm, `3` m, `4` in.

Több darabhoz küldje: `packages: [{ ref, weight, length, width, height, weight_unit, dimension_unit }]`. A `shipping_from` (címjegyzék-id) vagy `shipping_from_code` helyettesítheti a `sender_*` blokkot.

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

**Ellenőrzés:** a `result` true, és van ára (valamint tranzitnapok, ha a fuvarozó küldi). Ha nincs díj, javítsa a célt / csomagot / módot **mielőtt** létrehozna.

## 4. Címke létrehozása

Ez foglalja a küldeményt a fuvarozónál.

**REST:** `POST /api/v1/labelservice/submitOrder` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-submitOrder/post)

Ugyanaz a törzs, mint a 3. lépésben. Küldjön `Idempotency-Key`-t.

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/submitOrder \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dev-label-001" \
  -d '{
    "shipping_method": 59,
    "name": "Jane Recipient",
    "telephone": "5555555555",
    "email": "jane@example.com",
    "address_1": "6701 RUE HADLEY",
    "city": "Montreal",
    "province": "QC",
    "postcode": "H4E3R3",
    "country": "CA",
    "weight": 1,
    "length": 30,
    "width": 20,
    "height": 10,
    "dimension_unit": 2,
    "weight_unit": 2,
    "signature_option": 0,
    "insurance_option": 0,
    "package_type": "parcel",
    "ref": "DEV-LABEL-001",
    "sender_name": "Acme Warehouse",
    "sender_telephone": "5555555555",
    "sender_address_1": "2667 boul des sources",
    "sender_city": "Pointe-Claire",
    "sender_province": "QC",
    "sender_postcode": "H9S2H9",
    "sender_country": "CA"
  }'
```

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

```json
{
  "result": true,
  "id": 12345,
  "shipping_price": "12.50",
  "tracking_numbers": ["1Z999AA10123456784"],
  "external_id": "EXT_12345"
}
```

| Mező | Használat |
|---|---|
| `id` | Superroute rendelésazonosító — letöltés és törlés |
| `tracking_numbers` | Adja ezeket a vásárlónak; a követés elfogadja őket |
| `external_id` | Fuvarozói küldeményazonosító |
| `shipping_price` | Felszámított összeg |

**Ellenőrzés:** a `tracking_numbers` nem üres. Tárolja az `id`-t és a számokat. Ugyanaz az `Idempotency-Key` nem vehet második címkét.

## 5. PDF letöltése

**REST:** `POST /api/v1/labelservice/getShippingLabel` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-getShippingLabel/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/getShippingLabel \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "12345",
    "type": "ORDER_ID",
    "base64": 1
  }'
```

A `type` lehet `ORDER_ID`, `TRACKING_NUMBER` vagy `REF`. A `base64: 0` PDF-et streamel. Ez a **fuvarozó hivatalos címkéje**. A darabszámot a foglalás rögzíti.

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

**Ellenőrzés:** a PDF megnyílik, és a 4. lépés fuvarozói vonalkódját / követési számát mutatja. Nyomtasson egy tesztpéldányt, majd dobja ki — ne adjon tesztcímkét fuvarozónak.

## 6. Követés

Nincs token. Használjon egy számot a `tracking_numbers` közül:

```bash
curl https://YOUR_HOST/api/v1/tracking/1Z999AA10123456784
```

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

**GraphQL:**

```graphql
query {
  trackingPublic(trackingNumber: "1Z999AA10123456784") {
    result
    deliveried
    is_third_party_tracking
    data {
      tracking_event_status_id
      tracking_event_key
      description
      updated_at_localized
    }
    proofs { file_id type full_url signed_url }
  }
}
```

Az `is_third_party_tracking` true, ha az események a fuvarozótól jönnek. Ágazzon `tracking_event_status_id` / `tracking_event_key` szerint, ne `description` szerint. A legújabb esemény az első a `data`-ban. A korai események még «információ elküldve» lehetnek, amíg a fuvarozó be nem olvassa a csomagot. A `500` kézbesítve; a `proofs[]` akkor tartalmazhat aláírást (`type` `1`) vagy fotót (`type` `2`).

**Ellenőrzés:** a keresés a most létrehozott küldeményt adja. Ismeretlen szám: `result: false` / 404.

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

| Beállítás | Esemény | Mikor |
|---|---|---|
| `order_create_webhook_url` | `order.created` | `id` és fuvarozói követési számok mentése |
| `tracking_event_webhook_url` | `tracking.event` | Fuvarozói szkennelések, úton, kézbesítve |
| `order_status_change_webhook_url` | `order.status_change` | Állapot a rendszerében |
| `order_cancel_failed_webhook_url` | `order.cancel_failed` | Törlés elutasítva, mert a fuvarozó már bírja a csomagot |

**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)).

```bash
curl -X PUT https://YOUR_HOST/api/v1/webhook-settings \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order_create_webhook_url": "https://erp.example.com/hooks/superroute",
    "tracking_event_webhook_url": "https://erp.example.com/hooks/superroute",
    "webhook_sign_secret": "YOUR_LONG_RANDOM_SECRET",
    "webhook_verify_ssl": 1
  }'
```

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 `submitOrder` `order.created` eseményt ad azokkal a `tracking_numbers` értékekkel. Rossz titok: `401` a vevőjétől.

## 8. Törlés

Csak amíg a fuvarozó még engedi (általában az átvétel előtt).

**REST:** `POST /api/v1/labelservice/cancelShippingLabel` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-cancelShippingLabel/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/cancelShippingLabel \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"12345","type":"ORDER_ID"}'
```

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

A fuvarozó, aki már bírja a csomagot, elutasít — ez az `order.cancel_failed`.

**Ellenőrzés:** a második törlés biztonságos. A követés már nem kezeli a küldeményt élőként.

## 9. Napzárás (csak ha ez a mód megköveteli)

Egyes fuvarozók napi manifestet kérnek.

**REST:** `POST /api/v1/labelservice/endofday` — [REST kézikönyv](/api/documentation#/paths/v1-labelservice-endofday/post)

```bash
curl -X POST https://YOUR_HOST/api/v1/labelservice/endofday \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"shipping_method": 59}'
```

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

Hívja egyszer a szállítási nap utolsó címkéje után. Hagyja ki ezt a lépést, ha a 2. lépés módjának nincs ilyen követelménye.

**Ellenőrzés:** a sikertörzs (vagy a fuvarozó megerősítése) listázza a mai címkéket. Először tesztmódon futtassa.

## Teszlista

Használjon olyan célt, amelyet ellenőriz, és törölhető módot:

- [ ] A módlista nem üres; rögzített egy `id`-t.
- [ ] A díj árat ad arra a módra és célra.
- [ ] A Submit `tracking_numbers` értéket ad; ugyanaz az `Idempotency-Key` nem vesz második címkét.
- [ ] A címke PDF-je megnyílik, és a fuvarozói követési számot mutatja.
- [ ] A nyilvános követés megtalálja a küldeményt azon a számon.
- [ ] Megérkezik az `order.created`; a v2 aláírás ellenőrizhető.
- [ ] A törlés sikerül, **vagy** megerősítette, hogy ez a mód foglalás után nem törölhető.
- [ ] Ha a mód napzárást igényel, egy tesztfutás hiba nélkül lefut.
