İş ortağı yüzeyi sözleşmesi Başlarken
İş ortağı yüzeyine başlarken
İki kademeli kimlik
Bu yüzeyin taban yolu /api/partner/v1'dir ve yukarıdaki /api/v1 sözleşmesinin dışındadır. Her istek iki kimliği birlikte taşır; tek istisna, hesap anahtarının henüz var olmadığı üç uçtur: POST /accounts, POST /connections ve GET /connections/{id}. O istisna adıyla kayıtlıdır (DEC-271, DEC-277 ile genişletilmiş hâliyle; aşağıda kendi bölümlerinde). Üçü de yalnız X-App-Key ister, çünkü hesap anahtarı bu akışların çıktısıdır, girdisi olamaz.
| Başlık | Yanıtladığı soru | Nereden gelir |
|---|---|---|
X-App-Key |
hangi iş ortağı | Sevkora admin paneli üretir; hash'li saklanır, döndürülebilir |
Authorization: Bearer |
hangi hesap adına | hesap açılışında iş ortağına bir kez döner |
Vaat şudur: iki sırdan biri sızdığında sistem açılmaz. Sızan bir hesap anahtarı iş ortağı kimliği olmadan hiçbir şey yapamaz; sızan bir uygulama anahtarı tek başına hiçbir hesaba ulaşamaz.
Hesap anahtarı partner-api yeteneği taşır ve bu bilerek public-apiden ayrıdır: o anahtar tek başına /api/v1e giremez, dolayısıyla iki kademe atlanamaz. Cookie oturumu bu yüzeye giremez: /api/v1deki birinci taraf ayrıcalığı buraya taşınmaz.
Başlangıç sırası
Entegrasyonun ilk adımı hangisidir sorusunun tek cevabı budur. Sıra keyfî değildir: POST /accounts bir onay beyanı ister ve o beyanın çapası olan content_sha256 yalnız GET /legal-documents'ten gelir; o uç ise iki kademelidir, yani henüz sahip olunmayan bir hesap anahtarı ister. Kamuya açık ikiz GET /api/legal-documents bu alanı taşımaz ve bu bilinçlidir (DEC-282): özet, kabul beyanının çapasıdır ve beyanın olmadığı bir yüzeyde hiçbir ihtiyacı karşılamaz. Dolayısıyla ilk hesap anahtarı bağlanma akışından gelir:
| # | Adım | Kimlik | Sonuç |
|---|---|---|---|
| 1 | X-App-Key'i Sevkora'dan alın |
yok | Uygulama anahtarı (admin üretir; bir kez görünür) |
| 2 | POST /connections, mevcut bir Sevkora üyesinin e-postasıyla |
yalnız X-App-Key |
Talep satırı; hesabın sahibine Sevkora e-posta gönderir |
| 3 | Sahip e-postadaki bağlantıdan onaylar | yok | İş ortağının beyanı hiçbir koşulda yeterli değildir |
| 4 | GET /connections/{id} ile yoklayın |
yalnız X-App-Key |
Onay geldiyse account_key bir kez teslim edilir |
| 5 | GET /me ve GET /legal-documents |
iki kademeli | Anahtarlar doğrulanır; version + content_sha256 çiftleri alınır |
| 6 | POST /accounts ile yeni hesapları açın |
yalnız X-App-Key |
5. adımdaki çift geri gönderilir; hesap açılır |
2. adımdaki üye iş ortağının kendi Sevkora hesabı olabilir; entegrasyonu kurarken en pratik yol budur.
OLAY ABONELİKLERİ BU SIRANIN HİÇBİR YERİNE BAĞLI DEĞİLDİR (PA-50..PA-54)
POST /event-subscriptions yalnız X-App-Key ister, yani 1. adımdan hemen sonra kurulabilir. Bu bir kolaylık değil, DEC-359'un satın aldığı şeydir: abonelik iki kademeli olsaydı ancak 4. adımdan sonra kurulabilirdi ve 2-4. adımlarda düşen bir akışın account.creation_failed olayı hiçbir zaman duyulmazdı. Entegrasyona başlarken önerilen sıra, topup.succeeded, topup.failed ve account.creation_failed aboneliklerini 1. adımın hemen ardından kurmaktır.
Hesap anahtarı onaya kadar ölüdür
6. adımdan sonra dönen account_key ile, hesap sahibi kendisine giden e-postadaki bağlantıdan parolasını belirleyene kadar yapılan her istek 403 + partner_account_pending_activation döner. Anahtar canlanmıyorsa bakılacak ilk yer postacıdır: açılış e-postası gitmese de POST /accounts yine 201 döner (geçici bir SMTP arızası hesap açılışını kilitlememelidir). Yani 201, e-postanın ulaştığının kanıtı değildir.
Hata sınıfları: ne sızar, ne sızmaz
| Kod | Ne zaman | Gövde |
|---|---|---|
| 401 | uygulama anahtarı yok / tanınmıyor / iptal / süresi dolmuş; ya da hesap anahtarı yok | {"message":"Geçersiz iş ortağı kimliği."} |
| 403 | iş ortağı askıda | {"message":"İş ortağı erişimi askıya alınmıştır."} |
| 403 | hesap anahtarının kökeni sunulan uygulama anahtarıyla eşleşmiyor | {"message":"Hesap anahtarı bu iş ortağına ait değil."} |
| 429 | oran limiti (hesap anahtarı başına) | {"message":"..."} + Retry-After |
401 ailesinin dört nedeni de tek bir gövdeye düşer ve ayırt edilemez: aksi hâlde uç bir anahtar keşif aracına dönerdi. 403 ayrışır çünkü operasyonel olarak gereklidir; meşru iş ortağı askıya alındığını bilmelidir, köken uyuşmazlığı ise bir saldırı göstergesidir ve denetim izine yazılır.
İki yüzeyde birden yayımlanan yollar
Aşağıdaki yollar her iki yüzeyde de yayımdadır ve aynı denetleyiciye bağlıdır (DEC-345, DEC-351: kopyalama değil montaj). Gövde alanları, doğrulama kuralları ve durum geçişleri bu yüzden aynıdır; iş ortağı yüzeyi için ikinci bir iş mantığı yazılmadı. Ayrılan şeyler kimliğin kendisinden gelir ve üç başlıkta toplanır:
Hangi kimlik
/api/v1 tek kademelidir: istek yalnız Authorization: Bearer <anahtar> taşır ve o anahtar bir kullanıcıya, kullanıcı bir tenant'a bağlıdır. /api/partner/v1 iki kademelidir: X-App-Key (hangi iş ortağı) ile Authorization: Bearer (hangi hesap adına) birlikte sunulur. Hesap anahtarı partner-api yeteneği taşır ve tek başına /api/v1e giremez; public-api yetenekli bir v1 anahtarı da iş ortağı yüzeyine giremez. Kapı iki yönde de kapalıdır.
Hangi kapsam
İki yüzeyde de kayıtlar tek bir tenant'a kapatılır, ama tenant'ı seçen şey farklıdır: /api/v1de anahtarın sahibi olan kullanıcının tenant'ı, iş ortağı yüzeyinde hesap anahtarının bağlı olduğu hesabın tenant'ı. İş ortağı kendi verisini değil, adına çalıştığı hesabın verisini okur ve yazar. Kapsam iş ortağı başına değil hesap başına çizilir: aynı iş ortağının iki hesabı birbirinin kaydına ulaşamaz. Taşıyıcı hesabı yazma uçlarında (PA-61..PA-64) bu kapsam bir de yön taşır: iş ortağı hesabın taşıyıcı kimliğini adına yazar, ama hiçbir yüzey o kimliği geri okutmaz; denetim satırı hesap sahibinin üyesine yazılır ve bildirim hesabın tüm üyelerine gider.
Hangi hata dalları
İş ortağı yüzeyinde v1'de karşılığı olmayan ret dalları vardır: uygulama anahtarı yok, tanınmıyor, iptal edilmiş ya da süresi dolmuş (401; bu nedenler tek gövdeye düşer ve ayırt edilemez), iş ortağı askıda (403), hesap anahtarının kökeni sunulan uygulama anahtarıyla eşleşmiyor (403), hesap sahibi parolasını henüz belirlemedi (403). Oran limitinin sayacı da başkadır: /api/v1de anahtar başına, iş ortağı yüzeyinde hesap anahtarı başına. Tek istisna kendi-hesap doğrulama ucudur (PA-59 ve PA-63): onun sayacı iki yüzeyde de hesap sahibi üye ve taşıyıcı hesabı başınadır, çünkü koruduğu şey taşıyıcıya karşı yapılan kimlik denemesidir. Bir yolun v1 tarafındaki doğrulama ve iş kuralı hataları (422 ve ailesi) ise aynen geçerlidir, çünkü onları üreten denetleyici aynıdır.
Çift yayımlanan yolların tamamı aşağıdadır. Tablo mekanik olarak bağlıdır: bir yol bu kılavuzda iki yüzeyde birden yayımlandığı hâlde buraya yazılmazsa, ya da burada yazılıp bir yüzeyden kalkarsa, iki yüzeyin uç kümesini tabloyla karşılaştıran sözleşme testi kırmızıya döner.
Kapsamı adıyla yazılıdır: o karşılaştırma bu kılavuzun kendi uç sayfalarından türetilir, canlı rota tablosundan değil. Bir yol iki yüzeyde de çalıştığı hâlde v1 uç sayfası bu kılavuzda yazılmamışsa çift hiç oluşmaz, tablo onu istemez ve sözleşme testi boş küme üzerinde yeşil döner. Bu yüzden tablonun tamlığı ikinci bir ölçüyle, karşılaştırmanın bir ucunu CANLI rota tablosundan okuyan .specforge/evidence/TASK-481/yuzey.py ile bağlanır; bugün iki ölçü de sapmasızdır. Bilinen tek örnek GET /user/credit'ti: uç iki yüzeyde de yayımdaydı, iş ortağı ikizi PA-28 yazılıydı, v1 sayfası yoktu ve kapı bunu göremiyordu. Sayfa TASK-482'de yazıldı (PA-65) ve satır aşağıdadır.
| Yol | /api/v1 |
/api/partner/v1 |
|---|---|---|
GET /shipments |
PA-01 | PA-30 |
GET /shipments/{id} |
PA-02 | PA-31 |
POST /shipments |
PA-03 | PA-38 |
PATCH /shipments/{id} |
PA-04 | PA-41 |
POST /shipments/{id}/cancel |
PA-05 | PA-42 |
GET /shipments/{id}/label |
PA-06 | PA-43 |
GET /shipments/{id}/carrier-process |
PA-55 | PA-56 |
GET /shipments/{id}/quotes |
PA-18 | PA-39 |
POST /shipments/{id}/confirm |
PA-19 | PA-40 |
GET /warehouses |
PA-07 | PA-33 |
GET /warehouses/{id} |
PA-08 | PA-35 |
POST /warehouses |
PA-09 | PA-34 |
PATCH /warehouses/{id} |
PA-10 | PA-36 |
DELETE /warehouses/{id} |
PA-11 | PA-37 |
GET /carrier-accounts |
PA-12 | PA-44 |
POST /carrier-accounts |
PA-57 | PA-61 |
PATCH /carrier-accounts/{id} |
PA-58 | PA-62 |
POST /carrier-accounts/{id}/verify |
PA-59 | PA-63 |
DELETE /carrier-accounts/{id} |
PA-60 | PA-64 |
GET /webhooks |
PA-13 | PA-45 |
GET /webhooks/{id} |
PA-14 | PA-47 |
POST /webhooks |
PA-15 | PA-46 |
PATCH /webhooks/{id} |
PA-16 | PA-48 |
DELETE /webhooks/{id} |
PA-17 | PA-49 |
GET /invoices |
PA-20 | PA-29 |
GET /user/credit |
PA-65 | PA-28 |
Tabloda olmayan bir iş ortağı ucu, kural olarak v1'de karşılığı bulunmayan ve yalnız bu yüzeyde yaşayan bir uçtur: kimlik kurulumu, hukuki metin sürümleri, hesap açma, bağlanma akışı, hesap profili ve bakiye yükleme. Onlar bu bölümün kendi sözleşmesidir ve v1'de aranmamalıdır.
Bu yüzeydeki uçlar
Bağlanma
-
GET
/api/partner/v1/meİş ortağı kimlik doğrulama PA-21 -
GET
/api/partner/v1/legal-documentsHukuki metin sürümleri PA-22 -
POST
/api/partner/v1/accountsHesap açma PA-23 -
POST
/api/partner/v1/connectionsBağlanma talebi PA-24 -
GET
/api/partner/v1/connections/{id}Bağlanma durumu PA-25
Hesap
-
GET
/api/partner/v1/account/profileHesap profili okuma PA-26 -
PATCH
/api/partner/v1/account/profileHesap profili güncelleme PA-27 -
GET
/api/partner/v1/user/creditBakiye okuma PA-28
Okuma
-
GET
/api/partner/v1/invoicesFatura listesi PA-29 -
GET
/api/partner/v1/shipmentsGönderi geçmişi listesi PA-30 -
GET
/api/partner/v1/shipments/{id}Gönderi geçmişi detayı PA-31 -
GET
/api/partner/v1/shipments/{id}/carrier-processTaşıyıcıdan canlı süreç görünümü PA-56
Bakiye
Adresler
-
GET
/api/partner/v1/warehousesAdres defteri listesi PA-33 -
POST
/api/partner/v1/warehousesAdres oluşturma PA-34 -
GET
/api/partner/v1/warehouses/{id}Adres detayı PA-35 -
PATCH
/api/partner/v1/warehouses/{id}Adres güncelleme PA-36 -
DELETE
/api/partner/v1/warehouses/{id}Adres silme PA-37
Gönderi işlemleri
-
POST
/api/partner/v1/shipmentsGönderi oluşturma PA-38 -
GET
/api/partner/v1/shipments/{id}/quotesFiyat teklifi PA-39 -
POST
/api/partner/v1/shipments/{id}/confirmGönderi onayı PA-40 -
PATCH
/api/partner/v1/shipments/{id}Ölçü düzeltmesi PA-41 -
POST
/api/partner/v1/shipments/{id}/cancelGönderi iptali PA-42 -
GET
/api/partner/v1/shipments/{id}/labelEtiket çıktısı PA-43
Taşıyıcı hesapları
-
GET
/api/partner/v1/carrier-accountsTaşıyıcı hesapları PA-44 -
POST
/api/partner/v1/carrier-accountsKendi-hesap satırı açma PA-61 -
PATCH
/api/partner/v1/carrier-accounts/{id}Kendi-hesap satırı güncelleme PA-62 -
POST
/api/partner/v1/carrier-accounts/{id}/verifyKendi-hesap kimliğini doğrulama PA-63 -
DELETE
/api/partner/v1/carrier-accounts/{id}Kendi-hesap satırını devre dışı bırakma PA-64
Webhooks
-
GET
/api/partner/v1/webhooksWebhook aboneliği listesi PA-45 -
POST
/api/partner/v1/webhooksWebhook aboneliği oluşturma PA-46 -
GET
/api/partner/v1/webhooks/{id}Webhook aboneliği detayı PA-47 -
PATCH
/api/partner/v1/webhooks/{id}Webhook aboneliği güncelleme PA-48 -
DELETE
/api/partner/v1/webhooks/{id}Webhook aboneliği silme PA-49
Olay abonelikleri
-
GET
/api/partner/v1/event-subscriptionsOlay aboneliği listesi PA-50 -
POST
/api/partner/v1/event-subscriptionsOlay aboneliği oluşturma PA-51 -
GET
/api/partner/v1/event-subscriptions/{id}Olay aboneliği detayı PA-52 -
PATCH
/api/partner/v1/event-subscriptions/{id}Olay aboneliği güncelleme PA-53 -
DELETE
/api/partner/v1/event-subscriptions/{id}Olay aboneliği silme PA-54