İş ortağı yüzeyi sözleşmesi Gönderi işlemleri PA-40
Gönderi onayı
POST/api/partner/v1/shipments/{id}/confirm
> Künye: TASK-392; REQ-021 KK-7, DEC-345, DEC-043, DEC-181c/d.
BU UÇ PARA KESER
İş ortağı, hesap sahibinin cüzdanından harcama yapan bir fiili tetikler. Bu, DEC-345'in bilinçli sonucudur - aksi hâlde gömülü entegrasyon çalışmazdı - ve iki kelepçeyle sınırlıdır: para yalnız hesap sahibinin kendi cüzdanından çıkar, ve yetersiz bakiye dalı fail-closedtır.
Amaç
Taslağı onaylamak: ücret kesilir, taşıyıcı siparişi kurulur, gönderi CREATED döner. Senkrondur; kalıcı bir READY durumu yoktur.
Yetki
İki kademeli kimlik: X-App-Key + Authorization: Bearer. Hesap anahtarı partner-api yeteneği taşır ve tek başına /api/v1e giremez.
Sıra tasarımdır (strict-prepaid, DEC-043)
ücret taşıyıcı çağrısından önce kesilir. Ücreti durduran her koşulda taşıyıcıya sıfır istek gider.
Yetersiz bakiye FAIL-CLOSED'dır
422 döner, gönderi oluşmaz, taslak DRAFT kalır, kısmi durum birikmez ve cüzdan değişmez.
İstek
carrier_code zorunlu; auto en ucuz adayı seçer. account_model opsiyoneldir (dealer ya da own_account) ve /api/v1 PA-19 ile BİREBİR aynı sözleşmeyi taşır: aday kimliği (carrier_code, account_model) çiftidir, alan gelmezse dealer okunur ve auto ile own_account birlikte gönderilemez.
KENDİ HESABI SEÇİLDİĞİNDE PARA HİÇ ÇIKMAZ (DEC-363)
Yukarıdaki birinci kelepçe ("para yalnız hesap sahibinin cüzdanından çıkar") burada ÜÇÜNCÜ bir hâl kazanır: hesap sahibinin kendi doğrulanmış taşıyıcı hesabıyla çıkan gönderide bakiye düşülmez, shipment_charges satırı yazılmaz, defter dokunulmaz ve meta.charge null döner. Bu bir "sıfır tutarlı kesim" DEĞİLDİR: geri alınacak ya da mutabakat edilecek bir satır hiç doğmaz. İş ortağı yüzeyi bu davranışı /api/v1 ile AYNI denetleyiciden alır, ikinci bir para yolu yoktur (DEC-345 montajı).
Başarı 200
gönderi detayı + meta.charge (net ücret fee_minor, KDV bileşenleri vat_rate_percent/vat_minor, cüzdandan düşen total_minor, para birimi ve tarife sürümü; kendi hesabı yolunda null). Zarf PA-06/PA-19 ile aynı üreticiden çıkar. Ücretin kesildiği fiilin kendi zarfında okunur; sonraki bakiyeye bakmak tek başına yetmez.
Hatalar
422 (yetersiz bakiye, fiyatlanamaz aday, taslak olmayan durum, eksik Idempotency-Key), 409 (aynı anahtar farklı gövde; ya da "işlem sürüyor": eşzamanlı tekrar, başka bir onay aynı taslağı yürütüyor ya da farklı taşıyıcının ayakta ücreti hâlâ taze; bu 409 saklanmaz, istemci aynı anahtarla yeniden dener), 404 (başka tenant'ın gönderisi); ayrıca 401, 403, 429.
Idempotency-Key
ZORUNLUDUR ve burada bir para güvenliği kelepçesidir: tekrarlanan bir onay ikinci kez ücret kesmez, kayıtlı yanıtı Idempotency-Replayed: true başlığıyla aynen oynatır. Farklı bir anahtarla gelen ikinci onay da ücret kesmez: durum kapısı VAR OLAN gönderiyi 200 ve meta.confirm.outcome="already_created" ile döndürür (TASK-490). 5xx yanıt saklanmaz, yani aynı anahtar yeniden denenebilir. "İşlem sürüyor" 409 yanıtları da saklanmaz: istemci AYNI anahtarla yeniden dener; ikinci kesimi saklama değil durum kapısı ve ücret yarışı önler. Süreci yarıda kesilen isteğin anahtarı da bekleme penceresi dolunca aynı anahtarla yeniden koşar.
curl -X POST "{{host}}/api/partner/v1/shipments/GONDERI_ULID/confirm" \
-H "Accept: application/json" \
-H "X-App-Key: SEVKORA_UYGULAMA_ANAHTARINIZ" \
-H "Authorization: Bearer SEVKORA_API_ANAHTARINIZ" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ISTEMCI_URETIMI_BENZERSIZ_DEGER" \
-d '{"carrier_code":"auto"}'