@hubcommerce/yurtici
v1.0.0-rc.0
Published
Yurtici Kargo KOPS SOAP SDK — createShipment, queryShipment, cancelShipment, iade kodu (saveReturnShipmentCode)
Maintainers
Readme
@hubcommerce/yurtici
Yurtiçi Kargo KOPS ShippingOrderDispatcherServices SOAP SDK — gönderi oluşturma, takip (normalize durum), iptal ve iade kodu (saveReturnShipmentCode).
Yalnızca sunucu tarafında kullanın. Web servis kullanıcı adı/şifresi içerir; tarayıcıya veya istemci bundle'ına koymayın.
- Node
>=20.10.0, ESM, runtime bağımlılığı yok (nativefetch) - Yalnızca HTTPS; varsayılan test ortamı (
testws.yurticikargo.com) - Ödeme tipine göre birden fazla credential seti
- Kapsam, tuzaklar, açık sorular: docs/CONFORMANCE.md · Adapter sınırı: docs/ADAPTER-CONTRACT.md
Kurulum
npm install @hubcommerce/yurticiYapılandırma
.env.example dosyasını .env olarak kopyalayın (commit etmeyin):
| Env | Açıklama |
|-----|----------|
| YURTICI_WS_USERNAME | Web servis kullanıcısı → "default" credential seti |
| YURTICI_WS_PASSWORD | Web servis şifresi |
| YURTICI_TEST_MODE | Varsayılan test. Yalnızca "0" canlıya (ws.yurticikargo.com) geçer |
Yurtiçi her ödeme tipi (gönderici ödemeli, alıcı ödemeli, tahsilatlı...) için ayrı web servis kullanıcısı verir. Birden fazla set programatik verilir (bu durumda env credential okunmaz):
import { createYurticiClient } from "@hubcommerce/yurtici";
const yurtici = createYurticiClient({
testMode: true,
credentialSets: {
sender_pays: { username: secrets.ykSenderUser, password: secrets.ykSenderPass },
receiver_pays: { username: secrets.ykReceiverUser, password: secrets.ykReceiverPass },
},
defaultCredentialKey: "sender_pays",
});Diğer seçenekler: language (varsayılan "TR"), endpointUrl (HTTPS zorunlu), requestTimeoutMs (30 sn), maxRetries (2, yalnızca okuma), retryBaseMs, debug, logger, fetch.
client.config credential değerlerini içermez (yalnızca credentialKeys); JSON.stringify(client) ve console.log(client) maskelidir. SDK istek gövdesini asla loglamaz.
Kullanım
Her metod YurticiResult<T> döner — throw etmez:
type YurticiResult<T> = { ok: true; data: T } | { ok: false; error: YurticiApiError };Gönderi oluştur
const created = await yurtici.createShipment({
cargoKey: "ZEY-R1001-OUT", // sizin benzersiz anahtarınız — sorgu/iptal bununla
invoiceKey: "ZEY-R1001",
receiverCustName: "Ayşe Yılmaz",
receiverAddress: "Atatürk Cad. No:1 D:2",
cityName: "Ankara",
townName: "Çankaya",
receiverPhone1: "5550000000",
desi: 3,
});
if (!created.ok) {
console.error(created.error.code, created.error.yurticiErrorCode, created.error.message);
} else if (!created.data.allSucceeded) {
// toplu gönderimde kalem bazlı hata olabilir
console.warn(created.data.items.filter((item) => !item.ok));
}Mutasyonlar (createShipment, cancelShipment, iade kodu) otomatik tekrar edilmez. Timeout sonrası tekrar göndermeden önce queryShipment ile kontrol edin.
Takip
const tracked = await yurtici.queryShipment({
keys: "ZEY-R1001-OUT", // veya dizi
keyType: "cargoKey", // "invoiceKey"
addHistoricalData: true, // hareket geçmişi
});
if (tracked.ok) {
for (const shipment of tracked.data.shipments) {
shipment.status; // "NOT_PROCESSED" | "ACCEPTED" | "IN_TRANSIT" | "DELIVERED" | "CANCELLED" | "UNKNOWN"
shipment.operationStatus; // ham: NOP / ISR / IND / DLV / CNL / ISC / BI
shipment.isTerminal; // DELIVERED | CANCELLED
shipment.trackingUrl;
shipment.item?.events; // [{ unitName, eventName, cityName, occurredAt, ... }]
}
}Detaylı sorgu (tahmini teslim tarihi vb.): yurtici.queryShipmentDetail({ keys, jsonData? }).
İptal
const cancelled = await yurtici.cancelShipment("ZEY-R1001-OUT");
// cancelled.data.items[0].status → "CANCELLED"İade kodu (kiralama dönüşü)
Müşteri, kodu Yurtiçi şubesine söyleyerek ürünü geri gönderir. Kod bir tarih penceresinde ve kullanım limitiyle geçerlidir:
const saved = await yurtici.saveReturnShipmentCode(
{
fieldName: "16", // ⚠ anlamı Yurtiçi ile teyit edilecek (CONFORMANCE S2)
returnCode: "ZEY-R1001",
startDate: new Date(eventDay), // Date → Europe/Istanbul YYYYMMDD; string olduğu gibi gider
endDate: new Date(eventDay.getTime() + 7 * 86_400_000),
maxCount: 1,
},
{ credentialKey: "sender_pays" }, // ⚠ hangi set — CONFORMANCE S3
);
await yurtici.cancelReturnShipmentCode({ fieldName: "16", returnCode: "ZEY-R1001" });Bağlantı testi
const connection = await yurtici.testConnection({ credentialKey: "receiver_pays" });
// ok + verified: true → kimlik doğrulandıHatalar
| error.code | Anlam |
|--------------|-------|
| NOT_CONFIGURED | Credential seti yok / bilinmeyen credentialKey |
| VALIDATION_ERROR | SDK girdi kontrolü — istek gönderilmedi |
| AUTH_ERROR | Yurtiçi kimlik hatası (outFlag≠0, errCode 1625 / 80265) |
| BUSINESS_ERROR | Yurtiçi iş hatası (outFlag≠0) — error.yurticiErrorCode, error.details |
| WS_EXCEPTION | SOAP fault + YurticikargoWSException → YurticiWsException (errorCode, errText) |
| SOAP_FAULT / HTTP_ERROR / PARSE_ERROR / TRANSPORT_ERROR | Protokol / taşıma |
Yurtiçi kimlik ve iş hatalarını SOAP fault olarak değil, HTTP 200 gövdesinde outFlag=1 ile döndürür; SDK bunları hata sonucuna çevirir.
Test
npm test --workspace=@hubcommerce/yurtici # fixture tabanlı, ağ yok
npm run qa:smoke --workspace=@hubcommerce/yurtici # credential varsa, yalnızca testwsTestlerde @hubcommerce/yurtici/testing: createFixtureFetch, REAL_* (gerçek testws yanıtları) ve SYNTHETIC_* fixture'lar.
Kapsam dışı (1.0.0)
createShipmentDetail, createShipmentWithDelivery — bkz. CONFORMANCE §2.
Lisans
MIT
