JetDiji
JetDiji Servis · Entegrasyon Rehberi Gönderi entegrasyonu · v2

JetDiji Servis Entegrasyon Rehberi

Gönderilerinizi JetDiji'ye nasıl açacağınızı, güncelleyeceğinizi ve takip edeceğinizi adım adım anlatır. Alan ve şema ayrıntıları API Referansı'nda; bu sayfa sıra, kural ve hata davranışını anlatır.

Önceki adı: Jetlogi Servis. Eski uçlar (/api/ShipmentsService/*) çalışmaya devam eder; belgeleri Eski sürüm (v1) sayfasındadır. Geçiş için 10. bölüme bakın.

1. Hızlı başlangıç

Üç komutla ilk gönderinizi açıp durumunu sorgulayın. Örnekler preprod ortamını kullanır; *** yerine kendi bilgilerinizi yazın.

  1. Token alın. Gövde form biçimindedir (application/x-www-form-urlencoded).
    BASE=https://api.preprod.jetdiji.com
    curl -s -X POST "$BASE/api/integration/v1/oauth/token" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials" \
      -d "client_id=***" \
      -d "client_secret=***"
    Yanıttaki access_token değerini saklayın (varsayılan 900 sn geçerli):
    TOKEN=<access_token>
  2. Gönderi oluşturun. Yazma isteklerinde X-Idempotency-Key zorunludur.
    curl -s -X POST "$BASE/api/integration/v2/shipments" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -H "X-Idempotency-Key: 7d0f4c4e-1b2a-4f7e-9c3d-5a6b7c8d9e0f" \
      -d '{
        "customerReference": "SIP-2026-000123",
        "productCode": "<ürün kodu>",
        "recipient": { "name": "<Alıcı Adı Soyadı>", "phone": "<05XXXXXXXXX>" },
        "destinationAddress": {
          "countryCode": "TR", "cityCode": "34", "districtCode": "1421",
          "addressLine": "<Açık adres>"
        }
      }'
    İlk çağrı 201 ve "replayed": false döner. Aynı komutu tekrar çalıştırın: aynı gönderi "replayed": true ile döner, ikinci kayıt açılmaz. Yanıttaki data.shipmentNumber değerini not edin.
  3. Durumu sorgulayın. Takip numarası henüz yoksa gönderi numarasını kullanın.
    curl -s "$BASE/api/integration/v2/shipments/<shipmentNumber>?include=movements" \
      -H "Authorization: Bearer $TOKEN"
    ?include=movements için token'da shipment.events.read scope'u olmalıdır; yoksa parametreyi kaldırın.

2. Ortamlar ve hesap

OrtamTaban adresNe zaman
Preprod (test)https://api.preprod.jetdiji.comGeliştirme ve test
Canlıhttps://api.jetdiji.comGerçek gönderiler
  • Doküman her ortamda /swagger/index.html adresindedir. "Try it out" yalnız test ortamında açıktır.
  • Hesap: client_id ve client_secret bilgilerini JetDiji ekibinden isteyin: info@jetlogi.com.
  • Talepte hangi ürün(ler) için entegrasyon yapacağınızı ve hangi uçları kullanacağınızı belirtin; scope'lar buna göre tanımlanır (bkz. 3. bölüm).
  • Gönderilerinizi web üzerinden de izleyebilirsiniz: https://panel.jetdiji.com.
  • Token'ı hangi ortamdan aldıysanız o ortamda kullanın.

Temel biçimler

  • Tüm gönderi uçları /api/integration/v2/ ile başlar. Token ucu /api/integration/v1/oauth/token adresinde kalır.
  • İstek ve yanıt gövdeleri JSON'dur (token ucu hariç). Tarih/saat alanları ISO 8601 döner.
  • Başarılı yanıt: { "success": true, "data": {…}, "requestId": "REQ-…", "correlationId": null }. Yazma uçlarında ek olarak replayed gelir.
  • İl ve ilçe kodla verilir: cityCode plaka kodudur (ör. 34), districtCode JetDiji ilçe kodudur (ör. Kadıköy 1421). Kod listelerini referans uçlarından alın: reference/cities ve reference/cities/{cityCode}/districts.

İsteğe bağlı izleme başlıkları

BaşlıkNe işe yarar
X-Correlation-IdKendi izleme kimliğiniz. Yanıtta ve correlationId alanında geri döner.
X-Request-Idİstek kimliği. Göndermezseniz sunucu REQ-<uuid> üretir. Her yanıtta X-Request-Id başlığı ve requestId alanı döner; destek talebinde bunu iletin.

3. Kimlik doğrulama

Servis OAuth 2.0 client credentials akışını kullanır.

  1. POST /api/integration/v1/oauth/token, Content-Type: application/x-www-form-urlencoded, gövdede grant_type=client_credentials.
  2. Kimliği iki yoldan biriyle gönderin: Authorization: Basic base64(client_id:client_secret) başlığı ya da client_id + client_secret form alanları. İkisi birlikte gelir ve çelişirse 401 invalid_client.
  3. İsterseniz scope alanında boşlukla ayrılmış liste verin. Boş bırakırsanız istemcinize tanımlı tüm scope'lar verilir; tanımlı olmayan scope isterseniz 400 invalid_scope.
  4. Yanıt: { "access_token": "…", "token_type": "Bearer", "expires_in": 900, "scope": "…" }. Yanıt Cache-Control: no-store ile gelir.
  5. Sonraki her istekte Authorization: Bearer <access_token> gönderin. Süre dolunca yeni token alın; yenileme (refresh) ucu yoktur.
KonuKural
Token süresiVarsayılan 900 sn. İstemcinize özel süre tanımlanabilir; her zaman 60–3600 sn arasındadır. Gerçek süreyi expires_in alanından okuyun ve süresi dolmadan biraz önce yenileyin.
Token biçimiİmzalı JWT. İçeriğine dayanmayın; yalnız Bearer olarak gönderin.
İptalİstemciniz pasifleşirse, geçerlilik tarihi dışına çıkarsa ya da JetDiji tüm token'larınızı iptal ederse uçlar 401 CUSTOMER_API_TOKEN_REVOKED döner. Yeni token alın; yine alamıyorsanız JetDiji ekibine yazın.
Saklamaclient_secret ve token'ı sunucu tarafında güvenli yerde tutun; tarayıcıya, loga ya da URL'ye yazmayın.
Token hatalarıToken ucu OAuth biçiminde döner: { "error": "…", "error_description": "…" }. Kodlar 5. bölümde.

Scope'lar ve uçlar

ScopeKapsamUçlar
shipment.createGönderi oluşturmaPOST shipments
shipment.readDurum ve evrak okumaGET shipments/{trackingNumber}, lookup/customer-reference/{…}, lookup/transaction/{…}, {trackingNumber}/required-documents, reference/cities, reference/cities/{cityCode}/districts
shipment.updateGüncelleme ve hazırlık kararıPATCH {trackingNumber}, PATCH {trackingNumber}/address, PUT {trackingNumber}/products, PUT {trackingNumber}/customer-reference, POST {trackingNumber}/preparation-status
shipment.events.readHareket geçmişiGET {trackingNumber}/movements; durum uçlarında ?include=movements
shipment.cancelİptalPOST {trackingNumber}/cancel, POST lookup/transaction/{transactionId}/cancel

İptal uçları shipment.cancel scope'unu ister. shipment.update iptal yetkisi vermez. İptal kullanacaksanız bu scope'u hesap talebinizde belirtin.

Scope eksikse uç 403 CUSTOMER_API_SCOPE_FORBIDDEN döner. Scope, istemcinizin güncel tanımıyla birlikte kontrol edilir: tanımınızdan çıkarılan bir scope, eski token'da olsa bile kullanılamaz.

4. Gönderi yaşam döngüsü

Bir gönderinin entegrasyon tarafındaki tipik yolculuğu. Parantez içindeki adımlar isteğe bağlıdır.

Gönderi kimlikleri

Oluşturma yanıtında dört kimlik döner. Hangisinin nerede kullanılacağı:

AlanKim üretirNe zaman doluNerede kullanılır
shipmentNumberJetDijiOluşturma anındaTüm shipments/{trackingNumber} yollarında her zaman geçerli. Saklayın.
trackingNumberJetDijiSonradan (ör. kart barkodu eşlenince); başta null olabilirAynı yollarda geçerli; dolduğunda tercih edilir.
customerReferenceSiz (zorunlu)İstekteGET lookup/customer-reference/{…} ile arama. Yol parametresine verilmez.
transactionIdSiz (isteğe bağlı; ör. Kuveyt HGS işlem no)İstekteGET lookup/transaction/{…} ile arama ve POST lookup/transaction/{…}/cancel ile iptal. Yol parametresine verilmez.
  1. (Kodları hazırlayın.) İl ve ilçe kodlarını GET reference/cities ve …/districts ile alıp önbelleğe alın. Kart
  2. Oluştur. POST shipments. Yanıttaki shipmentNumber'ı saklayın; trackingNumber oluşturma anında boş olabilir. Tüm {trackingNumber} yollarında gönderi numarası da kabul edilir. Kart
  3. (Güncelle.) Teslimden önce alıcı/adres (PATCH {trackingNumber} ya da …/address), ürün listesi (PUT …/products) ya da müşteri referansı (PUT …/customer-reference) değiştirilebilir. Bu uçlarda durum kısıtı yoktur. Kartlar
  4. (Hazırlık ve evrak.) Gerekli evrakları GET …/required-documents ile öğrenin. Ürününüzde onay adımı varsa gönderi 2041 Onay Bekleniyor aşamasına gelince kararınızı POST …/preparation-status ile iletin. Kartlar
  5. Durum ve hareket takibi. GET shipments/{trackingNumber} (ya da müşteri referansı / işlem numarasıyla arama). Geçmiş için ?include=movements ya da GET …/movements. Son durumlar: 5010 Teslim Edildi, 7020 İade Edildi, 5140 İmha Edildi, 8010–8030 İptal. Kartlar
  6. (İptal.) Sipariş sizin tarafınızda iptal olursa POST …/cancel. Gönderinin bulunduğu aşamada iptal yolu yoksa 409 döner. Kartlar

Güncelleme, hazırlık kararı ve iptal kayıtları durum kodu taşımaz; hareket listesinde görünmez. Sonucu durum sorgusuyla izleyin.

5. Hata yönetimi

Tüm v2 uçları aynı hata zarfını döner (şema ErrorResponse):

{ "success": false,
  "error": { "code": "VALIDATION_ERROR",
             "message": "The request body does not match CreateShipmentRequest.",
             "details": [ { "path": "recipient.phone", "message": "…" } ] },
  "requestId": "REQ-3f6c2a9e-…",
  "correlationId": null }
  • Yalnız error.code ve HTTP durumuna bakın. message İngilizcedir ve değişebilir.
  • details çoğunlukla null'dur. VALIDATION_ERROR'da her sorun için { "path", "message" } içerir. Gövdedeki bilinmeyen alan da 422 döner.
  • Token ucu farklı biçim kullanır: { "error": "invalid_client", "error_description": "…" }.

İstemci ne yapmalı

HTTPAnlamıNe yapın
400Başlık ya da gövde biçimi bozukİsteği düzeltin; tekrar denemeyin. IDEMPOTENCY_KEY_REQUIRED → anahtar ekleyin.
401Token yok, geçersiz, süresi dolmuş ya da iptalYeni token alıp isteği bir kez tekrarlayın. Yine 401 ise JetDiji'ye bildirin.
403Scope ya da ürün yetkisi yokTekrar denemeyin; yetki için JetDiji ekibine yazın.
404Gönderi, ürün, müşteri, sözleşme ya da şube yokKimliği kontrol edin. Kapsamınız dışındaki gönderi de 404 görünür.
409Çakışma ya da gönderinin durumu işleme uygun değilKodu okuyun: mükerrer kayıtta mevcut gönderiyi sorgulayın; durum uygun değilse güncel durumu sorgulayıp akışı yeniden değerlendirin. Aynı isteği körlemesine tekrarlamayın.
415Token ucunda Content-Type yanlışapplication/x-www-form-urlencoded kullanın.
422Alan değeri geçersizerror.details'teki alanı düzeltin.
500Beklenmeyen hataAynı X-Idempotency-Key ile artan aralıklarla tekrar deneyin; sürerse requestId ile bildirin.
503Kimlik doğrulama geçici olarak kullanılamıyorBekleyip tekrar deneyin.
Tüm hata kodları

Kimlik doğrulama (tüm uçlar)

HTTPKodNe zaman
401CUSTOMER_API_BEARER_REQUIREDAuthorization: Bearer … başlığı yok. Yanıtta WWW-Authenticate: Bearer döner.
401CUSTOMER_API_TOKEN_INVALIDToken imzası, süresi ya da içeriği geçersiz.
401CUSTOMER_API_TOKEN_REVOKEDİstemci pasif, geçerlilik dışı ya da token'lar iptal edilmiş.
403CUSTOMER_API_SCOPE_FORBIDDENGerekli scope token'da yok (include=movements için shipment.events.read dahil).
503CUSTOMER_API_AUTH_CONFIGURATION_ERRORSunucu yapılandırması eksik.
503CUSTOMER_API_AUTH_UNAVAILABLEİstemci kaydı okunamadı.

Token ucu (OAuth)

HTTPerrorNe zaman
400invalid_requestGövde okunamadı.
400unsupported_grant_typegrant_type client_credentials değil.
400invalid_scopeİstenen scope istemciye tanımlı değil.
401invalid_clientKimlik hatalı; istemci pasif ya da geçerlilik dışı. WWW-Authenticate: Basic döner.
415invalid_requestContent-Type form-urlencoded değil.
503server_errorSunucu yapılandırması geçici olarak kullanılamıyor.

İstek biçimi (yazma uçları)

HTTPKodNe zaman
400IDEMPOTENCY_KEY_REQUIREDX-Idempotency-Key yok ya da boş.
400INVALID_JSONGövde JSON değil, JSON nesnesi değil ya da boş. İptal uçlarında boş gövde serbesttir.
422VALIDATION_ERRORGövde şemaya uymuyor; bilinmeyen alan da bu hatayı verir.
409IDEMPOTENCY_KEY_REUSE_CONFLICTAnahtar başka bir istek için kullanılmış (bkz. 6. bölüm).

İş kuralları

HTTPKodUçNe zaman
404SHIPMENT_NOT_FOUNDGönderi uçlarıGönderi yok ya da ürün kapsamınız dışında.
404CUSTOMER_NOT_FOUNDOluşturMüşteri kaydı bulunamadı.
404PRODUCT_NOT_FOUNDOluşturproductCode müşteriniz için tanımlı değil.
404CONTRACT_NOT_FOUNDOluşturcontractCode bulunamadı.
404BRANCH_NOT_FOUNDAdres güncellemebranchCode şube kayıtlarında yok.
403PRODUCT_NOT_ALLOWED_FOR_CLIENTOluşturÜrün istemcinize açık değil.
409CUSTOMER_REFERENCE_DUPLICATEOluştur, referans değiştirBu customerReference başka bir siparişte.
409TRANSACTION_ID_DUPLICATEOluşturBu transactionId kullanılmış.
409EXTERNAL_REFERENCE_DUPLICATEOluşturBu externalReference kullanılmış.
409PRODUCT_BARCODE_DUPLICATEOluştur, ürün değiştirBarkod başka bir gönderide güncel.
409CARD_INTAKE_MATCH_REQUIREDOluştur (Kart)Depoda kabul edilmiş kartla barkod eşleşmedi.
409PRODUCT_PUBLISHED_WORKFLOW_NOT_FOUND, PRODUCT_WORKFLOW_NOT_CONFIGURED, WORKFLOW_DEFINITION_NOT_FOUND, WORKFLOW_INITIAL_STEP_NOT_FOUND, WORKFLOW_ALREADY_STARTED, REQUIRED_FIELDSOluşturÜrünün iş akışı başlatılamadı. JetDiji ekibine bildirin.
409BRANCH_CODE_AMBIGUOUSAdres güncellemeŞube kodu birden çok konuma denk geliyor.
409BRANCH_GEOGRAPHY_INCOMPLETEAdres güncellemeŞube adresinde il/ilçe eksik.
409CUSTOMER_PARTY_BINDING_REQUIREDAdres güncellemeMüşteriniz şube kayıtlarına bağlı değil.
409PREPARATION_STATUS_NOT_ALLOWEDHazırlık kararıGönderi onay beklemiyor.
409EXTERNAL_APPROVAL_REQUEST_NOT_FOUNDHazırlık kararıGönderinin onay talebi yok.
409PREPARATION_DECISION_FAILED ve akış/onay kodları (ör. APPROVAL_REQUEST_NOT_FOUND, EXTERNAL_APPROVAL_DECISION_INVALID, EXTERNAL_APPROVAL_CONTINUE_REQUIRES_APPROVED)Hazırlık kararıKarar uygulanamadı.
409CANCELLATION_NOT_CANONICALLY_AVAILABLEİptalGönderinin bulunduğu aşamada iptal yolu yok.
409WORKFLOW_NOT_FOUNDİptalGönderinin iş akışı yok.
409CANCELLATION_FAILED ve akış kodlarıİptalİptal uygulanamadı.
422DESTINATION_GEOGRAPHY_INVALIDOluştur, güncellecityCode + districtCode geçerli bir il/ilçe çifti değil.
422ORIGIN_GEOGRAPHY_INVALIDOluşturshipFrom.address il/ilçe kodu geçersiz.
422PLANNED_DELIVERY_AT_INVALIDOluşturplannedDeliveryAt geçerli tarih-saat değil.
422PRODUCT_CODE_REQUIREDOluşturproductCode boş.
422KUVEYT_HGS_TRANSACTION_ID_INT32_REQUIREDOluştur (HGS)transactionId int32 tam sayı metni değil.
422TRACKING_NUMBER_REQUIREDTakip no'lu yazma uçlarıYol parametresi boş.
422TRANSACTION_ID_REQUIREDİşlem no ile iptalYol parametresi boş.
500CUSTOMER_API_CONTRACT_DATA_INCOMPLETEDurum uçlarıGönderi verisi eksik (müşteri referansı ya da durum adı). requestId ile bildirin.
500CUSTOMER_API_CREATE_FAILED, CUSTOMER_API_SHIPMENT_UPDATE_FAILED, CUSTOMER_API_ADDRESS_UPDATE_FAILED, CUSTOMER_API_PRODUCTS_UPDATE_FAILED, CUSTOMER_API_CUSTOMER_REFERENCE_UPDATE_FAILED, CUSTOMER_API_PREPARATION_STATUS_FAILED, CUSTOMER_API_CANCEL_FAILEDİlgili yazma ucuBeklenmeyen hata. Aynı anahtarla tekrar deneyin.

6. Idempotency ve tekrar deneme

Ağ kesintisinde aynı işlemi güvenle tekrarlayabilmeniz için tüm yazma uçları (POST/PATCH/PUT) X-Idempotency-Key başlığını zorunlu ister. Yoksa 400 IDEMPOTENCY_KEY_REQUIRED.

  1. Her yeni işlem için yeni bir anahtar üretin (UUID önerilir) ve isteği göndermeden önce işlemle birlikte saklayın.
  2. Yanıt alamazsanız (zaman aşımı, 5xx) aynı anahtar ve aynı gövdeyle tekrar deneyin.
  3. Yanıtta "replayed": true görürseniz işlem daha önce uygulanmıştır; yeniden uygulanmadı. data gönderinin güncel değerlerini taşır.
  4. Farklı bir işlem için asla eski anahtarı kullanmayın; 409 IDEMPOTENCY_KEY_REUSE_CONFLICT alırsınız.
UçReplay sayılan409 dönen
OluşturAynı anahtar + aynı customerReference → mevcut gönderi, 201, replayed: trueAynı anahtar başka customerReference ya da başka müşteri/ürünle. Gövdenin geri kalanı karşılaştırılmaz.
Adres değiştir (…/address)Aynı anahtar + aynı gönderiAynı anahtar başka gönderiyle. Gövde karşılaştırılmaz.
Alıcı/adres güncelle, ürün, müşteri referansı, hazırlık kararı, iptalAynı anahtar + aynı gönderi + aynı gövdeAynı anahtar başka gönderi ya da farklı gövde ile.
  • Anahtarlar işlem türüne göre ayrı tutulur: aynı anahtarı oluşturma ve güncelleme için kullanmak çakışma üretmez, ama bunu yapmayın.
  • İki iptal ucu (takip no ve işlem no) aynı anahtar alanını paylaşır.
  • Aynı anahtarla eşzamanlı gelen iki istekten biri işlemi uygular, diğeri replay olarak döner.
  • Hazırlık kararında aynı karar daha önce uygulandıysa yeni anahtarla da replayed: true dönebilir.

7. Uç uç kartlar

Her kart aynı şablonu izler: Amaç, İstek, Yanıt, İş kuralları, Hata durumunda. Yollar /api/integration/v2/ önekiyle yazılmamıştır (token ucu hariç). Tüm yazma uçlarında Authorization ve X-Idempotency-Key başlıkları gerekir.

1Token al

POST /api/integration/v1/oauth/token · scope gerekmez

AmaçClient credentials ile Bearer token almak.
İstekForm: grant_type=client_credentials, client_id, client_secret (ya da Basic başlık), isteğe bağlı scope.
Yanıt200: access_token, token_type: "Bearer", expires_in, scope.
İş kurallarıSüre 60–3600 sn (varsayılan 900). Refresh yok. Ayrıntı: 3. bölüm.
Hata durumunda401 invalid_client → bilgileri kontrol edin; 400 invalid_scope → scope listesini daraltın; 415 → Content-Type.
2İl ve ilçe kodlarını listele

GET reference/cities · GET reference/cities/{cityCode}/districts · shipment.read

AmaçAdreste gönderilecek cityCode ve districtCode değerlerini öğrenmek.
İstekGövde yok. İlçeler için yol parametresi cityCode (il listesindeki code).
Yanıt200: data: [{ code, name }]. İller plaka sırasıyla (1 Adana … 81 Düzce), ilçeler ada göre sıralı. Örnek: İstanbul 34 → Kadıköy 1421, Üsküdar 1708.
İş kurallarıListede görünen her il + ilçe çifti gönderide kabul edilir. Liste nadiren değişir; yanıtı 1 saat önbelleğe alabilirsiniz. Her gönderide tekrar çağırmayın.
Hata durumunda404 CITY_NOT_FOUND → il kodunu il listesinden alın. Gönderide 422 DESTINATION_GEOGRAPHY_INVALID alırsanız listeyi yenileyip kodu yeniden eşleyin.
3Gönderi oluştur

POST shipments · shipment.create

AmaçYeni gönderi açmak ve ürünün iş akışını başlatmak.
İstekZorunlu: customerReference (1–191), productCode (1–100), recipient.name (1–200), recipient.phone (1–50), destinationAddress (countryCode 2 harf, cityCode, districtCode, addressLine 1–1000). İsteğe bağlı: transactionId, externalReference, productBarcode, identityNumber, recipient.email, destinationAddress.neighborhood / branchCode, shipFrom, packages[], documents[] (Base64, en çok 10.000.000 karakter), products[], additionalData (metin değerli), shipmentChargeType (ACCOUNT_OWNER | RECIPIENT | SENDER_ADDRESS), contractCode, packageCount (≥1), totalWeight, plannedDeliveryAt (ISO), priorityCode (varsayılan NORMAL), additionalDescription (≤2000), labelRequest (PDF | ZPL). Tüm sınırlar API Referansı'nda.
Yanıt201, replayed ile: shipmentNumber, trackingNumber (boş olabilir), customerReference, transactionId; trackingUrl, label, returnLabel şimdilik null.
İş kurallarıcustomerReference, transactionId, externalReference müşteri içinde tekil. İl/ilçe yalnız kodla. Ürüne özel kurallar: 9. bölüm.
Hata durumunda409 CUSTOMER_REFERENCE_DUPLICATE → gönderi zaten var; GET lookup/customer-reference/{…} ile sorgulayın. 422 DESTINATION_GEOGRAPHY_INVALID → il/ilçe kodu. 403 PRODUCT_NOT_ALLOWED_FOR_CLIENT → ürün yetkisi.
4.1Alıcı ve adresi güncelle

PATCH shipments/{trackingNumber} · shipment.update

AmaçAlıcı adı, telefonu, e-postası ve/veya teslim adresini kısmi güncellemek.
İstek{ "recipient"?: { name?, phone?, email? }, "destinationAddress"?: <doğrudan adres | { branchCode }> }. En az biri; recipient içinde en az bir alan.
Yanıt200, replayed ile; data: shipmentNumber, trackingNumber, customerReference, transactionId.
İş kurallarıGönderilmeyen alan değişmez. email: null e-postayı siler. Durum kısıtı yok.
Hata durumunda404 BRANCH_NOT_FOUND, 409 BRANCH_* → şube kodunu kontrol edin; 422 DESTINATION_GEOGRAPHY_INVALID → il/ilçe kodu.
4.2Teslim adresini değiştir

PATCH shipments/{trackingNumber}/address · shipment.update

AmaçYalnız teslim adresini değiştirmek.
İstekDoğrudan adres { countryCode, cityCode, districtCode, neighborhood?, addressLine } ya da { branchCode }. İkisi karışık gönderilemez.
Yanıt200, replayed ile; gönderi kimlikleri.
İş kurallarıŞube kodunda adres, şubenin kayıtlı adresinden alınır. Durum kısıtı yok. İşlem numaranız varsa önce lookup/transaction/{transactionId} ile takip numarasını bulun.
Hata durumunda3.1 ile aynı; anahtar çakışmasında gövde karşılaştırılmaz (bkz. 6. bölüm).
4.3Ürün listesini değiştir

PUT shipments/{trackingNumber}/products · shipment.update

AmaçGönderinin ürün listesini tamamen yenilemek.
İstek{ "products": [ { "name"?: ≤255, "barcode"?: ≤191 } ] }, en çok 100 eleman; [] listeyi temizler.
Yanıt200, replayed ile; gönderi kimlikleri.
İş kurallarıEski ürün barkodları kapatılır, yenileri yazılır. İlk barkod gönderinin ürün barkodu olur.
Hata durumunda409 PRODUCT_BARCODE_DUPLICATE → barkod başka gönderide güncel.
4.4Müşteri referansını değiştir

PUT shipments/{trackingNumber}/customer-reference · shipment.update

AmaçSipariş numaranız değiştiğinde gönderiyi yeni numarayla eşlemek.
İstek{ "customerReference": "<1–191>" }
Yanıt200, replayed ile; data.customerReference yeni değer.
İş kurallarıEski referans kapatılır; sonraki referans aramaları yeni değerle yapılır.
Hata durumunda409 CUSTOMER_REFERENCE_DUPLICATE → değer başka siparişte kullanılıyor.
5.1Gerekli evrakları listele

GET shipments/{trackingNumber}/required-documents · shipment.read

AmaçGönderi için zorunlu evrakları öğrenmek.
İstekGövde yok.
Yanıt200; data[]: documentId, documentCode, name, description, contentBase64. Evrak yoksa [].
İş kurallarıYalnız zorunlu ve iptal edilmemiş evraklar, evrak sırasıyla. Ad ve açıklama gönderiye özel değer yoksa evrak tanımından (Türkçe) gelir. contentBase64 yalnız içerik açıkça tanımlıysa dolar; operasyonun çektiği görüntüler dönmez.
Hata durumunda404 SHIPMENT_NOT_FOUND.
5.2Hazırlık kararı gönder

POST shipments/{trackingNumber}/preparation-status · shipment.update

AmaçOnay bekleyen gönderi için onay ya da ret kararını iletmek.
İstek{ "decision": "APPROVE" | "REJECT_REMATCH" | "REJECT_RELEASE" }
Yanıt200, replayed ile; gönderi kimlikleri.
İş kuralları
decisionEski statusIDSonuç
APPROVE1Onaylanır, iş akışı devam eder.
REJECT_REMATCH2Reddedilir; ürün stoğa döner ve yeniden eşlenir.
REJECT_RELEASE5Reddedilir; ürün stoğa döner, ayrı sonuçlanır, etiket serbest bırakılır.
Yalnız onay bekleyen (2041 Onay Bekleniyor) gönderilerde çalışır.
Hata durumunda409 PREPARATION_STATUS_NOT_ALLOWED → gönderi onay beklemiyor; durumu sorgulayın. 409 EXTERNAL_APPROVAL_REQUEST_NOT_FOUND → onay talebi yok.
6.1Takip numarasıyla durum sorgula

GET shipments/{trackingNumber} · shipment.read (+ shipment.events.read)

AmaçGüncel durum, alt durum ve nedeni öğrenmek.
İstekİsteğe bağlı ?include=movements (virgülle ya da tekrarlanarak; bilinmeyen değer yok sayılır).
Yanıt200; data: shipmentNumber, trackingNumber, customerReference, transactionId, productCode, status { code, name, fullCode, fullName }, reason { code, name } | null, deliveryDate, recipient (ad), movements (include yoksa null). outputNumber, productNumber, appointmentDate şimdilik null.
İş kurallarıYol parametresi takip numarasıyla ya da gönderi numarasıyla eşleşir. Kodlar kanonik (8. bölüm).
Hata durumunda404 SHIPMENT_NOT_FOUND; 403 → include=movements için shipment.events.read eksik; 500 CUSTOMER_API_CONTRACT_DATA_INCOMPLETE → requestId ile bildirin.
6.2Müşteri referansıyla durum sorgula

GET shipments/lookup/customer-reference/{customerReference} · shipment.read (+ shipment.events.read)

AmaçGönderiyi sipariş numaranızla bulup durumunu almak.
İstek / Yanıt5.1 ile aynı.
İş kurallarıÖnce güncel referans kaydında birebir, sonra büyük harfe çevrilmiş değerle aranır; bulunamazsa siparişin customerReference alanına bakılır.
Hata durumunda5.1 ile aynı.
6.3İşlem numarasıyla durum sorgula

GET shipments/lookup/transaction/{transactionId} · shipment.read (+ shipment.events.read)

AmaçGönderiyi işlem numaranızla bulup durumunu almak; güncelleme öncesi takip numarasını öğrenmek.
İstek / Yanıt5.1 ile aynı.
İş kurallarıÖnce güncel işlem no kaydında (birebir ya da büyük harf), bulunamazsa gönderinin transactionId alanında aranır.
Hata durumunda5.1 ile aynı.
6.4Hareket geçmişini listele

GET shipments/{trackingNumber}/movements · shipment.events.read

AmaçGönderinin durum geçmişini almak.
İstekGövde yok.
Yanıt200; data[]: occurredAt, statusCode, statusName, fullStatusCode, fullStatusName, reasonCode, reasonName; eski tarihten yeniye.
İş kurallarıYalnız durum kodu taşıyan hareketler listelenir. Güncelleme, hazırlık kararı ve iptal kayıtları ile taşıyıcıya özel iç olaylar görünmez.
Hata durumunda404 SHIPMENT_NOT_FOUND; 403 → scope eksik.
7.1Gönderiyi iptal et

POST shipments/{trackingNumber}/cancel · shipment.cancel

AmaçGönderiyi müşteri talebiyle iptal etmek.
İstekGövde boş ya da {}. Alan gönderilirse 422.
Yanıt200, replayed ile; gönderi kimlikleri.
İş kurallarıİptal, 9425 Müşteri Talebi nedeniyle gönderinin akışındaki iptal adımına geçirilerek uygulanır. Kuveyt HGS onay bekleme aşamasındaki gönderide iptal, REJECT_RELEASE kararı olarak uygulanır; HGS gönderisi zaten iptal adımındaysa başarılı döner. shipment.update iptal yetkisi vermez.
Hata durumunda409 CANCELLATION_NOT_CANONICALLY_AVAILABLE → bu aşamada iptal edilemez; durumu sorgulayıp JetDiji ile görüşün. 403 → shipment.cancel eksik.
7.2İşlem numarasıyla iptal et

POST shipments/lookup/transaction/{transactionId}/cancel · shipment.cancel

AmaçGönderiyi işlem numaranızla bulup iptal etmek.
İstek / Yanıt / İş kuralları6.1 ile aynı. İki iptal ucu aynı anahtar alanını paylaşır.
Hata durumunda6.1 ile aynı; ek olarak 422 TRANSACTION_ID_REQUIRED.

8. Durum, alt durum ve neden kodları

v2 her zaman kanonik JetDiji kodlarını döner. Adlar Türkçedir.

Yanıt alanıAnlamı
status.code / statusCodeAna durum (4 hane)
status.fullCode / fullStatusCodeAlt (detay) durum
reason.code / reasonCodeNeden

Ana gruplar

KodGrupKodGrup
1000Sipariş5000Teslim
1100Alım5100Teslim Edilemedi
2000Hazırlık6000Devir
2100Kontrol7000İade
3000Transfer8000İptal
4000Dağıtım

Durumlar (statusCode)

KodAdNot
1010Sipariş Alındı
1110Alım Bekliyor
1120Alım TamamlanamadıNeden zorunlu (PUF_01–PUF_06)
2010Hazırlıkta
2020Alıcı AksiyonuNeden zorunlu
2030Eşleme
2040Onay
2110Kontrolde
2120Düzeltme Bekliyor
3010Transfer Bekliyor
3020Transferde
3030Düzeltme Bekliyor (transfer)
4010Teslimat Şubesinde
4020Dağıtımda
5010Teslim EdildiSon durum; neden = teslim alan tipi (9201–9207)
5020Teslim EdildiEvrak takip aşaması
5110Teslim EdilemediNeden zorunlu
5120Banka Şubesine DönüşHGS
5130İmha Bekliyor
5140İmha EdildiSon durum
6010Teslim EdilemediDevir / tekrar döngüsü
6110Yeniden İşlem Bekliyor
7010İade Bekliyor
7020İade EdildiSon durum
7030İade Edilecek
8010Müşteri Kaynaklı İptalSon durum
8020Alıcı Kaynaklı İptalSon durum
8030Operasyon Kaynaklı İptalSon durum
Alt durumlar (fullStatusCode)
KodÜst durumAd
10111010Sipariş Kontrolünde
10121010Sipariş Düzeltme Bekliyor
11111110Alım Planlandı
11121110Operasyon Onayı Bekliyor
11131110Alım Ertelendi
11141110Alım Tamamlandı
20112010Gönderi Hazırlanıyor
20212020Adres Güncelleme
20222020Randevu
20312030Eşleme Bekliyor
20412040Onay Bekleniyor. Hazırlık kararı (4.2) bu aşamada beklenir.
20422040Onaylandı
21112110Teslimat Kanıtı
21212120Eksik/Hatalı İşlem
30113010Transfer Çıkışı Planlandı
30123010Partner Kabulü Bekliyor
30213020Teslimat Şubesine Transferde
30223020Merkeze Transferde
30313030Yeniden Yönlendirme Bekliyor
40114010Planlanan Gün Bekleniyor
40124010Kurye Ataması Bekliyor
40134010Yeniden Yönlendirme Bekliyor
40214020Dağıtıma Çıktı
40224020Teslimat İşleminde
50115020Evrak Merkeze Transfer Bekliyor
50125020Evrak Merkezde
50135020Evrak Merkezde Kontrol
50145020Evrak Hazırlanıyor
50155020Evrak Müşteriye Teslim Edildi
50165020Evrak Arşivlendi
5111 / 60115110 / 6010Alıcıya Ulaşılamadı
5112 / 60125110 / 6010Alıcı Kabul Etmiyor
5113 / 60135110 / 6010Teslimat Sağlanamadı
61116110Yeni Aksiyon Bekliyor
70117010İade Süresi Bekliyor
70127010İade Merkeze Transfer Bekliyor
70137010İade Merkezde
70147030İade Hazırlanıyor
70157030İade Sevkiyata Çıktı
70217020İade Müşteriye Teslim Edildi
80118010Alım İptal
80128010Sipariş İptal
80218020Alıcı İptal Talebi
80228020Alıcı İletişim Sonuçsuz
80238030Kayıp
Neden kodları (reasonCode)
KodAd / not
9101Eksik/Hatalı Bilgi
9102Müşteri Kaynaklı
9103Operasyon Kaynaklı
9104Alıcı Kaynaklı
9105Operasyonel Engel
9106Hizmet Alanı Dışı
9107Partner Uygun Değil
9108Partner Kabul Etmedi
9111Tekrar İşlem/Devir
9114İade (transfer)
9115Evrak (transfer)
9116Devir: dağıtıma tekrar çıkış
9117Normal: dağıtıma ilk çıkış
9201–9207Teslim alan: Kendisi, Birinci Derece Akraba, Kardeşi, Sekreter, Güvenlik/Muhaberat, Banka Şubesi, Vekili
9301DLF-01 Alıcıya Ulaşılamadı
9302DLF-02 Alıcı Adreste Yok
9303DLF-03 Alıcı Teslimatı Reddetti
9304DLF-04 Hatalı/Eksik Adres
9305DLF-05 Adresten Ayrılmış
9306DLF-06 Vefat
9307DLF-07 İleri Tarih Talebi
9308DLF-08 Kimlik Doğrulanamadı
9310DLF-10 Evrak İşlemi Tamamlanamadı
9312DLF-12 - Hatalı / Eksik Adres
9313DLF-13 Operasyonel Engel
9314DLF-14 Mücbir Sebep
9410Alıcı iptali: Talebinden Vazgeçti
9411Alıcı iletişim sonuçsuz: Numara Hatalı
9412Alıcı iletişim sonuçsuz: Kullanım Dışı
9413Alıcı iletişim sonuçsuz: Cevaplanmadı
9414Alıcı iletişim sonuçsuz: Yanlış Numara
9415Alıcı iletişim sonuçsuz: Süre Doldu
9420Alım iptali: Ürün Bulunamadı
9421Alım iptali: Ürün Hazır Değil
9422Alım iptali: Ürün Teslim Edilmedi
9423Alım iptali: Kayıt Bulunamadı
9424Mükerrer Kayıt
9425Müşteri Talebi. API iptali bu nedenle uygulanır.
9426Geçersiz Kayıt
PUF_01Ürün Hazır Değil
PUF_02Ürün Bulunamadı
PUF_03Ürün Teslim Edilmedi
PUF_04Yanlış Ürün/Seri No
PUF_05Eksik Ürün
PUF_06Hasarlı Ürün

9112, 9113, 9401–9404 artık kullanılmaz; yeni kayıtlarda beklemeyin.

  • Neden adı müşteriye gösterilen addır; JetDiji'nin iç adından farklı olabilir (ör. 9312).
  • Kod listesine yeni değerler eklenebilir. Bilinmeyen kodu hata saymayın; name alanını gösterin.

9. Profil farkları

Davranış farkları istemcinizin bağlı olduğu üründen gelir. Aynı uçlar herkes için geçerlidir.

Ürün kapsamı

  • İstemciniz bir ürüne bağlıysa yalnız o ürünün gönderilerini görür ve değiştirir. Başka üründeki gönderi 404 SHIPMENT_NOT_FOUND görünür; başka ürünle oluşturma 403 PRODUCT_NOT_ALLOWED_FOR_CLIENT döner.
  • Ürüne bağlı olmayan istemci, müşterinin tüm ürünlerini görür.
  • Tüm sorgular kendi müşteri hesabınızla sınırlıdır.
KonuKuveyt Türk HGS (KUVEYT_HGS)Kuveyt Türk Kart (KUVEYTTURK_CARD_DISTRIBUTION)
OluşturtransactionId zorunlu biçim: -2147483648 ile 2147483647 arasında, başında sıfır olmayan tam sayı metni (422 KUVEYT_HGS_TRANSACTION_ID_INT32_REQUIRED). Depo kabulü gerekmez.Gönderi, depoda kabul edilmiş kartla barkoddan eşlenir; eşleşme yoksa 409 CARD_INTAKE_MATCH_REQUIRED.
Hazırlık kararıOnay akışında kullanılır: gönderi 2041 Onay Bekleniyor aşamasındayken APPROVE / REJECT_REMATCH / REJECT_RELEASE.Kart gönderileri onay beklemez; uç 409 PREPARATION_STATUS_NOT_ALLOWED döner.
İptalOnay beklerken yapılan iptal REJECT_RELEASE kararı olarak uygulanır.Akıştaki iptal adımıyla, 9425 nedeniyle.
Durum kodlarıHer iki üründe de kanonik kodlar döner (8. bölüm). HGS'ye özel durum: 5120 Banka Şubesine Dönüş.

Token'daki profil kodu (ör. KUVEYTTURK_HGS_V2, KUVEYTTURK_CARD_V1) yalnız tutarlılık için kontrol edilir; v2 davranışını değiştirmez.

10. v1'den v2'ye geçiş

Eski /api/ShipmentsService/* uçları çalışmaya devam eder (Eski sürüm (v1)). Yeni entegrasyonlar ve geçişler v2'yi kullanmalıdır.

Kimlik doğrulama

  • Eski uçlarda her istek gövdesinde auth.userName / auth.password vardı. v2'de bir kez token alıp Authorization: Bearer … gönderirsiniz (3. bölüm).
  • Eski kullanıcı adı/şifre v2'de çalışmaz. v2 için JetDiji ekibinden client_id / client_secret isteyin.
  • Tüm yazma isteklerine X-Idempotency-Key ekleyin (6. bölüm).

Uç eşleme

#Eski uç (POST)Eski anahtarv2 karşılığıScope
1Create–POST shipmentsshipment.create
2UpdateProductcargoKeyPUT shipments/{trackingNumber}/productsshipment.update
3UpdateCustomerUniquniqnumberPUT shipments/{trackingNumber}/customer-referenceshipment.update
4RequiredDocumentListcargokeyGET shipments/{trackingNumber}/required-documentsshipment.read
5Update (alıcı adı + GSM + adres)transactionIDPATCH shipments/{trackingNumber}shipment.update
6UpdateAddresstransactionIDPATCH shipments/{trackingNumber}/address (takip no'yu önce lookup/transaction/{transactionId} ile bulun)shipment.update
7UpdateStatus (statusID 1/2/5)transactionIDPOST shipments/{trackingNumber}/preparation-statusshipment.update
8ShipmentStatecargoKeyGET shipments/{trackingNumber} (+ ?include=movements)shipment.read (+ shipment.events.read)
9ShipmentStatebyCustomerUniqNumbercustomerUniqNumberGET shipments/lookup/customer-reference/{customerReference} (+ ?include=movements)aynı
10BaseShipmentStatebyCustomerUniqNumbercustomerUniqNumber9 ile aynı uçaynı
11ShipmentStatebyTransactionIDtransactionIDGET shipments/lookup/transaction/{transactionId} (+ ?include=movements)aynı
12ShipmentCancelcargokeyPOST shipments/{trackingNumber}/cancelshipment.cancel
13ShipmentCancelbyTransactionIDtransactionIDPOST shipments/lookup/transaction/{transactionId}/cancelshipment.cancel
–Hareket geçmişi (stateHistory)–GET shipments/{trackingNumber}/movements ya da ?include=movementsshipment.events.read

Eski Base ve normal durum uçları aynı veriyi farklı zarfla dönüyordu (Base'de result sarmalayıcısı yoktu, errorCode sayıydı). v2'de tek zarf olduğu için ikisi tek uca eşlenir.

Kimlik eşleme

Eskiv2
cargoKeyYok. Yerine trackingNumber; takip numarası yoksa shipmentNumber da kabul edilir.
uniqnumber / customerUniqNumbercustomerReference
transactionIDtransactionId

Alan eşleme

Eski alanv2 alanı
acceptorName + acceptorSurNamerecipient.name (tek alan, ad soyad)
acceptorGSMrecipient.phone
acceptorAddressdestinationAddress.addressLine
acceptorCitydestinationAddress.cityCode (yalnız kod)
acceptorDistrictdestinationAddress.districtCode (yalnız kod)
neighborhooddestinationAddress.neighborhood
branchCodedestinationAddress.branchCode
products[].prodNameproducts[].name
products[].prodBarcodeproducts[].barcode
changeuniqnumbercustomerReference
statusID 1 / 2 / 5decision APPROVE / REJECT_REMATCH / REJECT_RELEASE
files[].fileNamename
files[].contentcontentBase64
files[].docGuiddocumentId
files[].customerDocCodedocumentCode

Örnek: eski Update → v2 PATCH

# Eski (gövde, özet)
{ "transactionID": "123456789",
  "acceptorName": "<Ad>", "acceptorSurName": "<Soyad>", "acceptorGSM": "<05XXXXXXXXX>",
  "acceptorCity": "İSTANBUL", "acceptorDistrict": "KADIKÖY", "acceptorAddress": "<Açık adres>" }

# v2: önce takip numarasını bulun
curl -s "$BASE/api/integration/v2/shipments/lookup/transaction/123456789" \
  -H "Authorization: Bearer $TOKEN"

# sonra güncelleyin (il/ilçe kodla)
curl -s -X PATCH "$BASE/api/integration/v2/shipments/<trackingNumber>" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: 0b8e9c1a-6f2d-4e3b-8a7c-1d2e3f4a5b6c" \
  -d '{ "recipient": { "name": "<Ad Soyad>", "phone": "<05XXXXXXXXX>" },
        "destinationAddress": { "countryCode": "TR", "cityCode": "34", "districtCode": "1421",
                                "addressLine": "<Açık adres>" } }'

Örnek: eski UpdateStatus → v2 hazırlık kararı

# Eski: { "transactionID": "123456789", "statusID": 1 }
curl -s -X POST "$BASE/api/integration/v2/shipments/<trackingNumber>/preparation-status" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: 5c4b3a29-1807-4f6e-9d5c-4b3a29180706" \
  -d '{ "decision": "APPROVE" }'

Önemli farklar

  • Durum kodları kanonik. v2 her zaman kanonik JetDiji kodlarını döner; eski uçlardaki müşteriye özel dış kod projeksiyonu (ör. 6020) yoktur. Sözlük için 8. bölüme bakın.
  • İl/ilçe adı yerine kod. Eski Update ve UpdateAddress il/ilçe adını da kabul ediyordu; v2 yalnız cityCode / districtCode kabul eder.
  • Boş dönen alanlar. outputNumber, productNumber, appointmentDate v2'de şimdilik null döner. cargoKey, cargoUrl, barcode / returnBarcode yoktur; create yanıtında trackingUrl, label, returnLabel şimdilik null.
  • Hareket geçmişi ayrı. Eskinin tek çağrıda verdiği stateHistory yerine ?include=movements ya da …/movements kullanın; ikisi de shipment.events.read ister.
  • İptal için ayrı scope. İptal uçları shipment.cancel ister; shipment.update yetmez.
  • Hazırlık kararı enum. statusID yerine decision: APPROVE = 1, REJECT_REMATCH = 2, REJECT_RELEASE = 5. Ön koşul aynıdır: gönderi onay bekliyor olmalı.
  • Kısmi güncelleme. Eski Update eksik GSM'i boş yazar ve adresi her zaman isterdi. v2 PATCH'te gönderilmeyen alan değişmez; adres isteğe bağlıdır.
  • Hata biçimi. Sayısal hata kodları yerine metin error.code ve HTTP durumu (5. bölüm).