E-Ticaret

Kargo Entegrasyonu: Yurtiçi, Aras ve MNG API'leri ile Çok Taşıyıcılı Mimari

21 Sep 2026
13 dakika okuma
İninia Teknoloji

Kargo entegrasyonu, bir e-ticaret ya da ERP sisteminin taşıyıcı firmaların servislerine bağlanarak gönderi oluşturması, barkod/takip numarası alması ve gönderi durumunu izlemesidir. Türkiye'de bu işin en önemli teknik gerçeği şudur: büyük taşıyıcıların çoğu hâlâ SOAP web servisi sunar, kimlik bilgisi HTTP başlığında değil istek gövdesinde taşınır ve her taşıyıcının kendi alan adlandırması vardır. Bu rehber, Yurtiçi ve Aras Kargo'nun canlı servis sözleşmelerinden okunmuş gerçek metot ve alan adlarıyla, tek bir taşıyıcıya kilitlenmeyen bir çok taşıyıcılı (multi-carrier) mimari nasıl kurulur onu anlatıyor.

Bu yazıdaki metot ve alan adları, taşıyıcıların yayımladığı WSDL sözleşmelerinden 24 Eylül 2026 tarihinde okunmuştur. Servis sözleşmeleri güncellenebilir; entegrasyona başlamadan önce taşıyıcıdan güncel dokümantasyonu ve test hesabını talep edin.

Kargo Entegrasyonu Aslında Kaç İş?

"Kargo entegrasyonu yapalım" cümlesi, teknik olarak birbirinden bağımsız beş işi kapsar. Teklif alırken ve kapsam yazarken bunları ayırın:

İş Ne yapar Zorluk
Gönderi oluşturmaSipariş → taşıyıcıda kayıt + takip numarasıDüşük-orta
Barkod / etiketYazdırılabilir kargo etiketi üretimiOrta (format çeşitliliği)
Durum takibiHareket kayıtlarının çekilip normalize edilmesiYüksek — durum sözlükleri uyuşmaz
İade / iade koduMüşterinin ücretsiz iade gönderebilmesiOrta
Tahsilatlı (kapıda ödeme)Tahsilat tutarı, tahsilat tipi, mutabakatYüksek — para işin içinde

Projelerin çoğunda ilk iş bir haftada biter ve ekip "kargo entegrasyonu bitti" der. Sonraki üç ay, durum takibi ve tahsilat mutabakatıyla geçer. Kapsamı baştan bu tabloya göre yazmak, o üç ayı planlı hale getirir.

Yurtiçi Kargo: KOPS Web Servisi

Yurtiçi Kargo entegrasyonu, SOAP tabanlı ShippingOrderDispatcherServices servisi üzerinden yapılır:

Endpoint : https://webservices.yurticikargo.com/KOPSWebServices/ShippingOrderDispatcherServices
WSDL     : ...ShippingOrderDispatcherServices?wsdl
Namespace: http://yurticikargo.com.tr/ShippingOrderDispatcherServices

# Metotlar
createShipment              // gonderi olustur
createShipmentDetail        // detayli gonderi olustur
createShipmentWithDelivery  // teslimat bilgisiyle olustur
cancelShipment              // gonderi iptal
queryShipment               // sorgulama / takip
queryShipmentDetail         // detayli sorgulama
saveReturnShipmentCode      // iade kodu olustur
cancelReturnShipmentCode    // iade kodu iptal

Kimlik doğrulama gövdededir

Bu servisin en çok şaşırtan yanı: kullanıcı adı ve şifre HTTP başlığında değil, her metodun kendi parametreleri arasındadır. WSDL'deki sözleşme şöyledir:

createShipment {
  wsUserName      : string
  wsPassword      : string
  userLanguage    : string
  ShippingOrderVO : ShippingOrderVO[]   // coklu gonderi destekli
}

queryShipment {
  wsUserName        : string
  wsPassword        : string
  wsLanguage        : string
  keys              : string[]   // sorgulanacak anahtarlar
  keyType           : int        // anahtarin turu (cargoKey / takip no vb.)
  addHistoricalData : boolean    // gecmis hareketler dahil edilsin mi
  onlyTracking      : boolean    // yalnizca takip bilgisi
}

Not: createShipment dil parametresini userLanguage, queryShipment ise wsLanguage olarak adlandırır. Aynı servis içinde bile isimlendirme tutarsızdır — bu tür sürprizler bu API ailesinde olağandır ve WSDL'i gerçekten okumanın neden şart olduğunu gösterir.

ShippingOrderVO: gönderi nesnesinin alanları

Alan Tip Anlamı
cargoKeystringSizin ürettiğiniz tekil anahtar. Idempotency anahtarınız budur.
invoiceKeystringFatura anahtarı
receiverCustName, receiverAddressstringAlıcı adı ve açık adres
cityName, townNamestringKod değil, metin. Yazım farkı gönderiyi reddettirir.
receiverPhone1..3, emailAddressstringİletişim
desi, kg, cargoCountdouble / intDesi, ağırlık, parça adedi — fiyatı bunlar belirler
ttInvoiceAmount, ttCollectionType, ttDocumentId, ttDocumentSaveTypedouble / long / stringTahsilatlı teslimat alanları (kapıda ödeme)
taxNumber, taxOfficeId, taxOfficeNamestring / longKurumsal alıcı vergi bilgileri
specialField1..3stringSerbest alanlar — sipariş no gibi kendi referanslarınız için
waybillNostringİrsaliye numarası

Yanıt tarafında shippingOrderResultVO döner; içinde count, jobId ve gönderi başına shippingOrderDetailVO listesi bulunur. Hata durumları ise YurticikargoWSException tipiyle taşınır ve iki alanı vardır: errorCode (int) ve errText (string).

Toplu çağrı uyarısı: createShipment bir dizi alır ve yanıt da dizi döner. Kısmi başarı mümkündür — 10 gönderiden 7'si oluşup 3'ü hata verebilir. Yanıtı "hepsi başarılı" varsayıp işlemek, sahada en sık görülen hatadır. Her gönderiyi kendi cargoKey'i üzerinden tek tek eşleştirin.

Aras Kargo: ASMX Servisi

Endpoint : https://customerws.araskargo.com.tr/arascargoservice.asmx
WSDL     : ...arascargoservice.asmx?WSDL

# Sik kullanilan metotlar
SetOrder                    // siparis/gonderi olustur
SetDispatch2                // gonderi kaydi (alternatif akis)
SetDispatchXML              // XML govdeli gonderi kaydi
GetOrder                    // siparis oku
GetOrderWithIntegrationCode // kendi entegrasyon kodunuzla oku
GetCargoInfo                // kargo bilgisi
GetCargoTransaction         // hareket kayitlari (takip)
GetCargoSearch              // arama
CancelDispatch              // iptal
GetPriceCalculation         // fiyat hesaplama
GetShipmentBarcode          // barkod
GetCityList / GetTown       // il / ilce listeleri
GetDuration                 // tahmini teslim suresi
Recall / CancelRecall       // iade cagirma

Kimlik doğrulama yine gövdededir: SetOrder(orderInfo, userName, password) ve SetDispatch2(orderInfo, userName, password). Dahası, Order nesnesinin kendi içinde de UserName ve Password alanları vardır — yani kimlik bilgisi iki katmanda birden taşınabilir.

Dikkat çekici bir ayrıntı: iki taşıyıcının veri modeli neredeyse aynı

Aras'ın OrderInfo nesnesinin alanlarını Yurtiçi'nin ShippingOrderVO'suyla yan yana koyduğunuzda tablo şöyle görünür:

Kavram Yurtiçi (ShippingOrderVO) Aras (OrderInfo)
Tekil anahtarcargoKeyCargoKey
Alıcı adıreceiverCustNameReceiverCustName
Desi / ağırlık / adetdesi, kg, cargoCountDesi, Kg, CargoCount
TahsilatttInvoiceAmount, ttCollectionTypeTtInvoiceAmount, TtCollectionType
Serbest alanlarspecialField1..3SpecialField1..3

Bu benzerlik tesadüf değil — Türkiye'deki kargo entegrasyon şemaları ortak bir geçmişten geliyor. Pratik sonucu: ortak bir iç gönderi modeli tasarlamak sandığınızdan kolay. Farklar isimlendirmede (camelCase / PascalCase) ve ek alanlarda yoğunlaşıyor: Aras ayrıca District, Quarter, Avenue, Street, CityCode, TownCode, PieceDetails, WorldWide gibi alanlar sunuyor. Yani ortak modeli en zengin taşıyıcıya göre kurup diğerlerine daraltarak eşlemek doğru yön.

MNG Kargo ve Diğerleri

MNG Kargo tarafında entegrasyon, geliştirici portalı üzerinden (apizone.mngkargo.com.tr) API anahtarı ile kullanılan servisler aracılığıyla yapılır. Portal, ürünleri üç başlıkta sunar: kargo takip, gönderi hazırlama ve barkod oluşturma. Burada uç nokta adreslerini ezberlemek yerine taşıyıcıdan güncel dokümantasyon ve test hesabı istemeniz gerekir — bu portal SOAP döneminin sözleşmelerinden farklı olarak sürümlenir ve değişir.

Genel kural: her taşıyıcıdan entegrasyona başlamadan önce üç şeyi yazılı olarak isteyin — (1) güncel teknik dokümantasyon, (2) test ortamı kimlik bilgileri, (3) hata kodları listesi. Üçüncüsü çoğu zaman verilmez ve verilmediğinde entegrasyonun hata yönetimi deneme-yanılmayla yazılır; bunu kapsam ve süre tahmininize yansıtın.

Çok Taşıyıcılı Mimari: Doğru Yerleşim

Tek taşıyıcıyla başlayan sistemlerin neredeyse tamamı 12 ay içinde ikinci taşıyıcıyı ekler — fiyat pazarlığı, bölgesel kapsama ya da hizmet kalitesi yüzünden. Bu yüzden ilk günden çok taşıyıcılı kurun; maliyeti düşüktür, sonradan dönüştürmek pahalıdır.

<?php

interface TasiyiciAdaptoru
{
    public function gonderiOlustur(Gonderi $gonderi): GonderiSonucu;

    public function gonderiIptal(string $tasiyiciReferansi): void;

    /** @return Hareket[] */
    public function hareketleriGetir(string $takipNo): array;

    public function etiketGetir(string $takipNo): Etiket;
}

// Kendi ic modeliniz - tasiyiciya ait HICBIR alan adi burada gecmez
final class Gonderi
{
    public function __construct(
        public readonly string  $referans,        // idempotency anahtari
        public readonly Alici   $alici,
        public readonly float   $desi,
        public readonly float   $kg,
        public readonly int     $parcaAdedi,
        public readonly ?int    $tahsilatKurus = null,
        public readonly ?string $siparisNo = null,
    ) {}
}

Bu arayüzün arkasında her taşıyıcı için bir adaptör yazılır. Adaptörün üç sorumluluğu vardır ve sadece bu üçü:

  1. İç modeli taşıyıcının alan adlarına eşlemek
  2. Taşıyıcının hatasını ortak bir istisna tipine çevirmek
  3. Taşıyıcının durum sözlüğünü ortak duruma normalize etmek

Durum normalizasyonu: en çok hafife alınan kısım

Her taşıyıcının kendi hareket açıklamaları vardır ve bunlar Türkçe serbest metindir. Müşteriye tek bir tutarlı zaman çizelgesi göstermek istiyorsanız ortak bir durum kümesi tanımlamanız gerekir:

enum GonderiDurumu: string
{
    case OLUSTURULDU      = 'olusturuldu';
    case TESLIM_ALINDI    = 'teslim_alindi';
    case TRANSFERDE       = 'transferde';
    case DAGITIMDA        = 'dagitimda';
    case TESLIM_EDILDI    = 'teslim_edildi';
    case TESLIM_EDILEMEDI = 'teslim_edilemedi';
    case IADE_SURECINDE   = 'iade_surecinde';
    case IPTAL            = 'iptal';
}

Eşleme tablosunu veritabanında tutun, kodda değil. Taşıyıcı yeni bir açıklama metni eklediğinde (ki ekler) yeni sürüm çıkmadan eşleme ekleyebilmelisiniz. Eşlenemeyen bir metinle karşılaşıldığında sistem sessizce "bilinmiyor" demez — kaydı işaretler ve operasyona bildirir. Bunu yapmayan ekipler, müşteri şikâyetinden öğrenir.

Idempotency: çift gönderi üretmeyin

Taşıyıcı servisleri zaman aşımına uğrar. Yanıt alamadığınızda gönderi oluşmuş da olabilir, oluşmamış da. Kör tekrar denemesi ikinci bir kargo etiketi üretir ve bu, gerçek para kaybıdır.

Çözüm, cargoKey alanını kendi tekil referansınızla doldurmaktır. Yanıt alamazsanız tekrar oluşturmayın — queryShipment (Yurtiçi) veya GetOrderWithIntegrationCode (Aras) ile o anahtarın durumunu sorgulayın ve ona göre karar verin.

<?php

public function gonderiOlusturGuvenli(Gonderi $gonderi): GonderiSonucu
{
    try {
        return $this->adaptor->gonderiOlustur($gonderi);
    } catch (TasiyiciZamanAsimi $e) {
        // KOR TEKRAR YOK - once gercekten olustu mu diye sor
        $mevcut = $this->adaptor->referanstanSorgula($gonderi->referans);

        if ($mevcut !== null) {
            return $mevcut;             // olusmus, ikincisini uretme
        }

        throw $e;                        // gercekten olusmamis, kuyruga geri koy
    }
}

Adres verisi: sessiz başarısızlığın kaynağı

Yurtiçi'nin cityName/townName alanları metindir. "Afyonkarahisar" ile "Afyon", "Şişli" ile "Sisli" farklı dizelerdir. Bu yüzden:

  • İl/ilçe listelerini taşıyıcının kendi servisinden çekin (Aras'ta GetCityList, GetTown) ve kendi veritabanınızla eşleyin.
  • Eşlemeyi kurulum zamanında yapın, gönderi anında değil. Gönderi anında yapılan arama, yoğun günde yavaşlar ve hata verir.
  • Türkçe karakter normalizasyonunu tek bir yardımcı fonksiyonda toplayın; her adaptörde ayrı ayrı yazılan normalizasyon er ya da geç ayrışır.

Tahsilatlı Teslimat: Para İşin İçine Girince

Kapıda ödeme, entegrasyonun en riskli parçasıdır çünkü artık veri değil para akar. Teknik olarak ttInvoiceAmount (tahsilat tutarı), ttCollectionType (tahsilat tipi) ve ttDocumentSaveType gibi alanlarla ifade edilir; fakat asıl iş, taşıyıcının size gönderdiği tahsilat mutabakat dosyasıyla kendi kayıtlarınızı karşılaştırmaktır.

Kurulması gereken minimum kontroller:

  1. Gönderi oluştururken beklenen tahsilat tutarını kendi tarafınızda kilitleyin; sipariş sonradan değişse bile gönderiye yazılan tutar değişmemeli.
  2. Taşıyıcının bildirdiği tahsilat ile beklenen tutarı her gün karşılaştırın; fark varsa gönderi bazında raporlayın.
  3. Tahsil edilmiş ama size aktarılmamış tutarların yaşlandırma raporunu tutun.

Bu, muhasebe entegrasyonuyla doğrudan ilişkilidir; banka tarafındaki mutabakat mimarisini Banka Entegrasyonu: Açık Bankacılık (ÖHVPS), MT940 ve Sanal POS Teknik Rehberi yazımızda anlattık. Faturalama tarafı için GİB e-Fatura ve e-Arşiv API entegrasyonu rehberine bakabilirsiniz.

Kendi Entegrasyonunu Yazmak mı, Entegratör Kullanmak mı?

Kendi entegrasyonunuz Kargo entegratörü
Başlangıç eforuTaşıyıcı başına ayrı işTek entegrasyon
Süregelen bakımSizdeSağlayıcıda
Maliyet yapısıTek seferlik geliştirmeGönderi başına / abonelik
Özel iş kuralı esnekliğiTamSağlayıcının modeliyle sınırlı
Bağımlılık riskiTaşıyıcıyaEntegratöre

Karar için pratik eşik: gönderi hacminiz düşük ve standart bir akışınız varsa entegratör; hacminiz yüksek, özel iş kurallarınız (bölgeye göre taşıyıcı seçimi, çok depolu sevkiyat, özel iade akışı) varsa kendi entegrasyonunuz. Ara durumda hibrit iyi çalışır: ana taşıyıcı için kendi adaptörünüz, kuyruktaki taşıyıcılar için entegratör — arayüz zaten ortak olduğu için bu karışım mimariyi bozmaz.

Süre ve Maliyet

ininia'da yazılım geliştirme 300–400 USD/adam-gün bandında, adam-gün dökümüyle fiyatlanır. Kargo entegrasyonu teklifi değerlendirirken şu kalemleri ayrı ayrı görmek isteyin — özellikle ikinci kalem, taşıyıcı sayısıyla çarpılır:

  • Ortak gönderi modeli + adaptör arayüzü (bir kez)
  • Taşıyıcı başına adaptör: oluşturma, iptal, takip, etiket
  • Durum normalizasyon tablosu ve yönetim arayüzü
  • Idempotency + kuyruk + yeniden deneme
  • Adres/il-ilçe eşleme ve normalizasyon
  • Tahsilatlı teslimat ve günlük mutabakat raporu (varsa)
  • Etiket üretimi ve yazdırma akışı

Kendi kapsamınız için aralık görmek isterseniz proje fiyat hesaplama aracımızı kullanabilirsiniz.

Sıkça Sorulan Sorular

Kargo API'ları REST mi, SOAP mu?

Türkiye'deki büyük taşıyıcıların yerleşik servisleri ağırlıklı olarak SOAP'tır: Yurtiçi Kargo ShippingOrderDispatcherServices, Aras Kargo ise ASMX tabanlı arascargoservice.asmx sunar. Daha yeni geliştirici portalları API anahtarıyla çalışan servisler sunabilir. Yani karma bir dünya; tek bir protokol varsayımıyla mimari kurmayın.

Kimlik bilgisi nasıl gönderiliyor?

Bu API ailesinde kimlik bilgisi genellikle HTTP başlığında değil, istek gövdesinde metot parametresi olarak taşınır (Yurtiçi'de wsUserName/wsPassword, Aras'ta userName/password). Bu, kimlik bilgilerinin istek loglarına sızma riskini artırır — log maskeleme kuralınızı baştan yazın.

Aynı gönderiyi iki kez oluşturmayı nasıl engellerim?

Kendi tekil referansınızı cargoKey (veya Aras'ta entegrasyon kodu) alanına yazın ve zaman aşımı durumunda kör tekrar denemesi yerine önce sorgulama metodunu çağırın (queryShipment, GetOrderWithIntegrationCode).

Kargo durumlarını nasıl standartlaştırırım?

Her taşıyıcının kendi serbest metin açıklamaları vardır. Kendi durum kümenizi tanımlayın ve eşleme tablosunu veritabanında tutun; eşlenemeyen metinleri sessizce yutmak yerine operasyona bildirin.

Kaç taşıyıcıyla başlamalıyım?

Tek taşıyıcıyla başlayın ama mimariyi çok taşıyıcılı kurun. Adaptör arayüzünü ilk günden tanımlamanın ek maliyeti düşüktür; tek taşıyıcıya gömülmüş bir sistemi sonradan ayırmak ise genellikle yeniden yazmak anlamına gelir.

Desi hesabını kim yapıyor?

Gönderi oluştururken desi ve ağırlığı siz bildirirsiniz (desi, kg, cargoCount); taşıyıcı ise kendi ölçümünü yapar ve fark çıkarsa faturaya yansıtır. Bu yüzden bildirilen ile faturalanan desi arasındaki farkı raporlamak, lojistik maliyetini kontrol etmenin en etkili yollarından biridir.

Test ortamı var mı?

Taşıyıcılar test hesabı verir, ancak bu genellikle talep üzerine ve sözleşme sürecine bağlı olarak açılır. Entegrasyona başlamadan önce test kimlik bilgilerini, güncel dokümantasyonu ve hata kodları listesini yazılı olarak isteyin; üçüncüsü verilmediğinde hata yönetimi deneme-yanılmayla yazılır ve süre tahmini kayar.

Sonuç

Kargo entegrasyonunun teknik zorluğu SOAP'ta ya da alan sayısında değil; çeşitlilikte ve kısmi başarıda. Her taşıyıcı aynı kavramı farklı adlandırır, her biri kendi durum sözlüğünü kullanır, toplu çağrılar kısmen başarılı olur ve zaman aşımları çift etiket üretebilir. Bu dört gerçeği baştan mimariye yazan bir sistem — ortak gönderi modeli, adaptör arayüzü, veritabanında tutulan durum eşlemesi ve sorgulamaya dayalı idempotency — yeni taşıyıcıyı bir haftada ekler. Yazmayan sistem ise her yeni taşıyıcıda baştan yazılır.

ininia olarak e-ticaret ve lojistik tarafında kargo entegrasyonları, çok taşıyıcılı sevkiyat altyapıları ve mutabakat hatları kuruyoruz. Kapsamımızı lojistik & kargo ve e-ticaret & perakende sayfalarında görebilir, ERP tarafındaki bağlantı için ERP entegrasyonları sayfasına bakabilir, kendi projeniz için iletişim sayfasından yazabilirsiniz.

Kaynaklar: Metot ve alan adları, taşıyıcıların yayımladığı canlı WSDL sözleşmelerinden 24 Eylül 2026 tarihinde okunmuştur — Yurtiçi Kargo webservices.yurticikargo.com/KOPSWebServices/ShippingOrderDispatcherServices?wsdl, Aras Kargo customerws.araskargo.com.tr/arascargoservice.asmx?WSDL. MNG Kargo bilgisi apizone.mngkargo.com.tr geliştirici portalından alınmıştır. Servis sözleşmeleri değişebilir; entegrasyona başlamadan önce taşıyıcıdan güncel dokümantasyonu teyit edin.

Bu konuda bir yazılım projesi mi planlıyorsunuz?

Projenizi birlikte analiz edip teknik yol haritasını çıkarabiliriz. Ücretsiz keşif görüşmesi için hemen yazın.

İninia Teknoloji

İstanbul Teknik Üniversitesi ARI Teknokent'te kurulu Ininia Teknoloji, 12+ yıllık deneyimle AR/VR, yapay zeka ve mobil uygulama alanlarında yenilikçi çözümler sunmaktadır.

Projeniz için profesyonel destek mi arıyorsunuz?

12+ yıllık deneyimimizle dijital dönüşümünüzü hızlandıralım.

Ücretsiz Görüşme Talep Et