# Vodič kroz izmene integracija

Svaka izmena ispod je strogo aditivna: postojeći endpoint-i, polja odgovora, HTTP statusni kodovi, bajtovi webhook payload-a i nasleđeno `Signature` zaglavlje ostaju nepromenjeni. Integracije koje ne preduzmu ništa nastavljaju da rade tačno kao i pre. Svaku funkciju usvojite nezavisno, bilo kojim redosledom.

Poslužuje se uživo na https://api.superlabel.ca/api/documentation/integration-updates?lang=sr (`?download=1` za čuvanje). Prateći dokumenti: OpenAPI (https://api.superlabel.ca/api/documentation?lang=sr), Postman kolekcija (https://api.superlabel.ca/api/documentation/postman-collection), rečnik i tok statusa (https://api.superlabel.ca/api/documentation/order-status-flow?lang=sr).

---

## 1. Otkazivanje po broju za praćenje (idempotentno)

`POST https://api.superlabel.ca/api/v1/orders/cancel` — navedite tačno jedno od `order_id`, `tracking_number`, `external_tracking_number`.

```json
POST /api/v1/orders/cancel
Authorization: Bearer <token>
{ "external_tracking_number": "WP1234567890" }
```

- Uspeh: `200 {"result":true,"id":123456,"already_cancelled":false,...}`
- Već otkazano (bezbedan ponovni pokušaj): `200` sa `"already_cancelled": true`
- Broj se poklapa sa više aktivnih porudžbina: `409` sa `"matched_order_ids": [...]` — pokušajte ponovo sa `order_id`.
- Nasleđeni `GET /v1/orders/{orderId}/cancel` ostaje nepromenjen.

## 2. Feed-ovi za inkrementalno usaglašavanje

Pokupite sve što se promenilo unutar vremenskog prozora; zahvaljujući kursorskoj paginaciji nijedan zapis se ne propušta niti duplira.

- `GET https://api.superlabel.ca/api/v1/orders-reconciliation?updated_from=&updated_to=&per_page=&cursor=`
- `GET https://api.superlabel.ca/api/v1/tracking-events/reconciliation?...`

`updated_from` / `updated_to` prihvataju unix vremenske oznake ili stringove u formatu `Y-m-d H:i:s` u vremenskoj zoni platforme. Pratite `next_cursor` dok `has_more` ne postane false; poredite pomoću unix polja `*_timestamp`, nikada pomoću stringova u lokalnom vremenu. Stavke događaja praćenja uključuju `occurred_at` / `occurred_timestamp` (vreme poslovnog nastanka; za istorijske redove jednako je vremenu kreiranja).

## 3. Mašinski čitljivi kodovi grešaka i praćenje zahteva

Odgovori na greške pri čestim create/cancel operacijama sada nose stabilno polje `code` uz nepromenjeni `message`:
`VALIDATION_FAILED`, `MISSING_IDENTIFIER`, `ORDER_NOT_FOUND`,
`ORDER_CANCEL_UNAUTHORIZED`, `ORDER_STATUS_NOT_CANCELLABLE`,
`ORDER_CANCEL_BLOCKED_THIRD_PARTY`, `LABEL_CANCEL_FAILED`,
`DUPLICATE_TRACKING_NUMBER`, `MULTIPLE_ORDERS_MATCHED`.
Kodovi su stabilni identifikatori — mogu se pojaviti novi, ali postojeći nikada ne menjaju značenje. Svaki API odgovor takođe vraća `X-Request-ID`; navedite ga kada prijavljujete problem.

## 4. Unapređenja detekcije duplikata

Uz `auto_deduplication=1`, unosi `exist_package_ref` / `exist_external_tracking_number` blokiranog kreiranja sada uključuju postojeći `order_id` i `order_ref`, a koverta nosi `"duplicate": true`. Opcioni strogi režim: pošaljite `strict_duplicate_check=1` da biste dobili HTTP `409` umesto nasleđenog `200` + `result:false` (izostavite flag da zadržite nasleđeno ponašanje).

## 5. Opcije grupnog kreiranja

- `per_order_transaction: 1` (na vrhu tela batch zahteva): svaka porudžbina se potvrđuje nezavisno — jedan neuspeh više ne poništava ostale. Ako se obrada prekine ranije, i dalje dobijate redove za sve što je završeno, plus završni red `{"result":false,"batch_aborted":true}`.
- Batch-evi sa više od 100 porudžbina dobijaju savetodavno zaglavlje odgovora `X-Batch-Size-Warning`; za velike količine radije koristite `POST /v1/client/batchOrderCreateAsync`.

## 6. Sinhronizacija datoteka dokaza o isporuci

Unosi `proofs[]` u odgovorima praćenja sada dodatno nose:

```json
{ "url": "...", "full_url": "...", "type": 2,
  "file_id": 234567, "uploaded_at": "2026-07-20 14:30:05",
  "uploaded_timestamp": 1784745005,
  "signed_url": "https://.../files/pod/234567?expires=...&signature=...",
  "signed_url_expires_at": 1784745005 }
```

Koristite `file_id` kao ključ za dedupliranje / inkrementalnu sinhronizaciju. `signed_url` je link sa rokom važenja (7 dana) — nakon isteka ponovo upitajte praćenje za novi. Trajni linkovi `url` / `full_url` ostaju nepromenjeni.

## 7. Webhook-ovi: v2 zaglavlja za potpis (sve isporuke)

Svaki webhook sada TAKOĐE šalje, uz nepromenjeno nasleđeno `Signature` zaglavlje:

| Zaglavlje | Značenje |
|---|---|
| `X-Webhook-Event-Id` | UUID, stabilan kroz ponovne pokušaje — koristite za dedupliranje |
| `X-Webhook-Timestamp` | unix sekunde u trenutku prvog slanja |
| `X-Webhook-Signature-V2` | HMAC-SHA256 od `"<timestamp>.<raw body>"` |

Verifikacija (bilo koji jezik): `expected = HMAC_SHA256(timestamp + "." + raw_body, your_secret)`; poređenje sa zaglavljem u konstantnom vremenu. Vremenska oznaka se fiksira pri prvom slanju i ponovo koristi pri ponovnim pokušajima (koji mogu trajati do ~3 sata), pa uparite širok prozor tolerancije sa dedupliranjem po `X-Webhook-Event-Id` umesto stroge replay granice. Vaša postojeća verifikacija nasleđenog `Signature` zaglavlja nastavlja da radi nepromenjeno — usvojite v2 kad god želite. Oba potpisa možete testirati na vašem endpoint-u sa stranice vodiča za webhook-ove (`/webhooks-guide`).

## 8. Webhook-ovi: opciona payload koverta

Postavite `webhook_payload_envelope = 1` u podešavanjima webhook-a da biste unutar JSON tela događaja u obliku objekta dobijali: `event_id`, `event_time` (ISO8601 sa pomerajem), `event_timestamp` (unix), plus — gde je primenljivo — `is_correction: true` (prethodno isporučena/predata porudžbina se vratila u tok) i `occurred_at` / `occurred_timestamp` na događajima praćenja. Bez ovog flag-a vaš payload ostaje bajt-po-bajt identičan kao pre. Payload-i u obliku liste (`order.create_async`) se nikada ne menjaju.

## 9. Novi webhook događaji (URL-ovi po izboru)

- `pod.files_updated` — fotografija/potpis isporuke je naknadno dodata ili uklonjena. Konfigurišite `pod_files_webhook_url`. Payload:
  `{"action":"added|removed","order_id":...,"order_ref":...,
  "tracking_number":[...],"external_tracking_number":[...],
  "file":{"file_id":...,"type":1|2,"note":null}, "event_id":..., ...}`
- `order.deleted` — porudžbina je trajno obrisana. Konfigurišite `order_deleted_webhook_url`. Payload: `{"action":"deleted","order_id":...,
  "order_ref":...,"tracking_number":[...],"external_tracking_number":[...],
  "event_id":..., ...}`

Oba događaja uvek uključuju polja koverte i šalju se samo kada je njihov URL konfigurisan.

## 10. Webhook-ovi: opcije isporuke

- **Više endpoint-a po događaju**: svako podešavanje webhook URL-a prihvata jedan URL (kao i do sada), listu razdvojenu zarezima ili JSON niz. Svaki endpoint dobija sopstveni ciklus isporuke i ponovnih pokušaja.
- **TLS verifikacija**: postavite `webhook_verify_ssl = 1` da odlazni pozivi verifikuju vaš sertifikat. Podrazumevano ostaje isključeno (istorijsko ponašanje).
- **order.created za sve tipove porudžbina**: postavite `order_created_webhook_all_types = 1` da proširite događaj kreiranja porudžbine i van porudžbina lokalne isporuke. Podrazumevano se zadržava istorijski opseg.
- **Tajne za potpisivanje**: nova podešavanja dobijaju jaku nasumičnu tajnu; postojeće tajne se nikada ne rotiraju automatski.

## 11. Opsezi API tokena i liste dozvoljenih IP adresa (opciono)

Pojedinačni tokeni mogu biti ograničeni na `orders:read`, `orders:write` i/ili `webhooks:manage`, kao i na listu dozvoljenih IP adresa. Neograničeni tokeni (podrazumevano, i svi ranije izdati tokeni) ponašaju se tačno kao i pre. Ograničeni token koji pozove van svojih opsega/IP adresa dobija `403`. Kontaktirajte podršku da biste ograničili token.

## 12. Slanje paketa prevoznika (Smart Locker)

Spoljni prevoznici šalju pakete u zonu za pripremu skladišta jednim grupnim pozivom. Opciono možete priložiti telefon/imejl primaoca kako bi primalac bio obavešten kodom za preuzimanje čim se paket smesti u pametni ormarić. Polja primaoca su opciona — endpoint ostaje unazad kompatibilan.

```json
POST https://api.superlabel.ca/api/v1/inventories/carrier-staging-stockin
Authorization: Bearer <token>
{ "carrier_id": 1, "warehouse_id": 10, "data": [
  { "carrier_reference_number": "TRK1", "ref": "REF1",
    "recipient_phone": "+14165550123", "recipient_email": "r@example.com" }
] }
```

```graphql
mutation($carrierId: Int!, $warehouseId: Int, $packages: Json) {
  submitCarrierPackages(carrierId: $carrierId, warehouseId: $warehouseId, packages: $packages)
}
```

- Autentifikacija: Bearer token kao i obično. Korisnički nalozi moraju imati ovlašćenje za otpremanje prevoznika (prevoznik + skladište); client, employee i partner nalozi koriste sopstveni opseg skladišta.
- Po paketu: member_number i/ili carrier_reference_number prema podešavanjima prevoznika; opciono carrier_order_id, batch, ref, grid_code (samo osoblje), recipient_phone, recipient_email.
- Svaki red odgovora vraća pickup_code; isti kod se dostavlja primaocu u obaveštenju o preuzimanju.

Kontakt primaoca se čuva šifrovano i nikada se ne vraća. Kada su navedeni i telefon i imejl, obaveštavaju se oba kanala; telefon/imejl imaju prednost nad obaveštenjem u aplikaciji putem članskog povezivanja.

## Garancija kompatibilnosti

Pogledajte politiku upravljanja izmenama: odgovori se menjaju samo aditivno, novi endpoint-i postoje uporedo sa starim, tela webhook-ova su podrazumevano zamrznuta, podrazumevane vrednosti se nikada ne menjaju, a ukidanja se najavljuju najmanje 30 dana unapred zaglavljima `Deprecation` / `Sunset`. Ove garancije sprovode automatizovani testovi kompatibilnosti na nivou bajtova pri svakom izdanju.