Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Uyumsoft E-Dönüşüm Web Servisi (SOAP API) PHP SDK

PHP Version License Zero Dependencies UBL Standard Protocol

Türkiye'nin lider e-Dönüşüm ve özel entegratör kuruluşlarından Uyumsoft için hazırlanmış, sıfır bağımlılığa (zero-dependency) sahip, PHP yerleşik ext-soap eklentisine dahi ihtiyaç duymadan doğrudan cURL + XML protokolü üzerinden haberleşen yeni nesil PHP SDK'sıdır.

Hem insan yazılımcılar hem de AI kodlama asistanları (Gemini, Claude, Cursor, Copilot vb.) için en ideal, tip güvenli (type-safe) ve dayanıklı e-Fatura / e-Arşiv entegrasyon altyapısını sunar.


🚀 Önemli Özellikler

  1. Bağımsız SOAP Motoru (ext-soap İhtiyacı Yok): Sunucularda PHP soap eklentisinin kurulu veya aktif olmasına gerek duymaz. Doğrudan cURL ve güvenli XML ayrıştırma (DOMDocument / SimpleXML) ile çalışır.
  2. Yerleşik WS-Security (WCF Uyumlu): PHP'nin standart SoapClient sınıfının desteklemediği wsse:Security, wsse:UsernameToken ve milisaniye hassasiyetinde UTC Zulu (wsu:Timestamp) başlıklarını otomatik üretir.
  3. UBL-TR 2.1 Fatura Derleyicisi: Gelir İdaresi Başkanlığı (GİB) standartlarına tam uyumlu UBL-TR 2.1 XML belgeleri üretir.
  4. Hassas KDV & Kuruş Dağılım Algoritması: Kalem bazlı indirimleri, genel sipariş iskontolarını ve kargo bedellerini oran bazlı KDV matrahlarına kuruşu kuruşuna paylaştırır; GİB şematron (schematron) yuvarlama hatalarını tamamen engeller.
  5. e-Arşiv İnternet Satışı Desteği: GİB e-Arşiv mevzuatının internet satışları için zorunlu kıldığı web sitesi, ödeme aracısı, ödeme türü, ödeme tarihi ve kargo taşıyıcı (VKN, unvan, sevk tarihi) bilgilerini eksiksiz yönetir.
  6. Akıllı Mükellef & Etiket Tespiti: Vergi kimlik numarasını sorgulayarak alıcının e-Fatura mükellefi olup olmadığını (IsEInvoiceUser) anında anlar; mükellef ise posta kutusu etiketlerini (GetUserAliasses), değilse e-Arşiv akışını devreye alır.
  7. Mükerrer Fatura Önleyici Ağ Kurtarma (Idempotent Recovery): Ağ kopması veya zaman aşımı anında faturayı körü körüne yeniden göndermek yerine uzaktaki UUID durumunu kontrol eder; mükerrer fatura kesilmesini önler.
  8. Resmî PDF ve Görsel Çıktı: Base64 ile şifrelenmiş resmî mühürlü PDF ve HTML önizleme çıktılarını tek metotla indirir.
  9. Kapsamlı Operasyon Kapsamı: Uyumsoft BasicHttpBinding_IIntegration WSDL servisinde tanımlı 64 web servis operasyonunun tamamını destekler.
  10. Yerleşik XML Güvenliği: XXE (XML External Entity) ve XML Bomb (Billion Laughs / DoS) saldırılarına karşı ham yanıtı ön filtrelemeden geçirir.

⚠️ En Büyük Entegrasyon Tuzakları ve Sahada Çözümleri

Gerçek e-ticaret ve ERP projelerinde Uyumsoft entegrasyonu yapan yazılımcıların karşılaştığı en kritik problemler ve bu SDK'nın getirdiği çözümler:

1. WS-Security Header & ext-soap Uyuşmazlığı

  • Tuzak: PHP'nin yerel SoapClient sınıfı WS-Security (wsse:Security, wsse:UsernameToken) standardını doğrudan desteklemez. Harici kütüphaneler kurulmadığında WCF servisi An error occurred when verifying security for the message veya HTTP 500 Internal Server Error döndürür.
  • SDK Çözümü: SDK, RFC ve OASIS standartlarına uygun Timestamp (5 dakikalık geçerlilik, milisaniye ve UTC Zulu Z formatı) ve UsernameToken bloklarını cURL zarfında sıfır bağımlılıkla kendisi oluşturur.

2. UBL XML Kök Etiket Çakışması (typedInvoiceElement Hatası)

  • Tuzak: Standart bir UBL-TR XML belgesi kök düğüm olarak <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"> taşır. Ancak Uyumsoft'un WCF SOAP servisi, SendInvoice ve ValidateInvoice çağrılarında faturanın iç düğümlerini <tem:Invoice> veya <tem:invoice> altında bekler. Dış <Invoice> etiketi olduğu gibi gönderilirse WCF Deserializer hata verir.
  • SDK Çözümü: UyumsoftClient, UBL belgesini bellekte ayrıştırarak kök <Invoice> etiketini ayıklar ve alt elemanları xmlns:cac ile xmlns:cbc ad alanlarıyla güvenle <tem:Invoice> içerisine enjekte eder.

3. GİB e-Arşiv İnternet Satışı Bilgileri Zorunluluğu

  • Tuzak: İnternet üzerinden sipariş alan e-ticaret siteleri e-Arşiv faturası keserken ProfileID = EARSIVFATURA kullanmak zorundadır. Ancak yalnızca bu profili seçmek yetmez; GİB kurallarına göre InternetSalesInfo (Web adresi, ödeme aracısı, ödeme türü, ödeme tarihi) ve ShipmentInfo (Kargo firması VKN'si, kargo adı ve sevk tarihi) zorunludur. Aksi halde fatura GİB tarafından reddedilir.
  • SDK Çözümü: InternetSalesInfoData nesnesi bu alanları yapılandırılmış olarak toplar ve SOAP zarfına otomatik ekler.

4. KDV Dağılımı ve Kuruş Yuvarlama Uyuşmazlığı

  • Tuzak: Bir faturada satır iskontoları ve sipariş geneli indirimler dağıtılırken KDV hariç matrah, satır KDV'si ve ödenecek tutar toplamları arasında 0.01 TL (1 kuruş) dahi yuvarlama farkı oluşursa GİB şematron doğrulaması faturayı reddeder.
  • SDK Çözümü: UblInvoiceBuilder, son kaleme kalan kuruş farkını tahsis eden algoritması ve KDV oranlarına göre gruplanmış TaxSubtotal mekanizması ile matematiksel tutarlılığı garanti altına alır.

5. Ağ Kopmalarında Mükerrer Fatura Riski (Idempotency Recovery)

  • Tuzak: Fatura gönderimi esnasında cURL zaman aşımına uğrarsa (örneğin sunucu 30 saniye yanıt vermezse), istek aslında Uyumsoft'a ulaşmış ve kuyruğa alınmış olabilir. Yazılım bunu "hata" sayıp faturayı tekrar gönderirse müşteriye 2 adet fatura kesilir.
  • SDK Çözümü: SDK, hata anında faturanın UUID veya LocalDocumentId bilgisiyle queryOutboxInvoiceStatus üzerinden uzaktaki durumu doğrulamayı sağlayan bir kurtarma (recovery) şablonu sunar.

6. e-Fatura ve e-Arşiv İptal Prosedürleri Farkı

  • Tuzak: e-Arşiv faturaları Uyumsoft API'si üzerinden CancelEArchiveInvoice metoduyla iptal edilebilir. Ancak alıcısına ulaşmış bir e-Fatura API'den doğrudan silinemez.
  • Doğru Akış: Ticari e-faturalarda alıcı 8 gün içinde portalından veya API'den SendDocumentResponse (RED) göndermelidir. Temel e-faturalarda ise alıcının iade faturası kesmesi veya harici itiraz (noter, KEP) yoluna başvurulması gerekir.

⚙️ Kurulum

Kütüphaneyi projenize Composer kullanarak dahil edebilirsiniz:

composer require emirhangungormez/uyumsoftapi

Composer kullanmıyorsanız, src/ klasöründeki dosyaları projenize doğrudan require_once ile dahil edebilirsiniz.


📖 Temel Kullanım Senaryoları

1. İstemciyi Başlatma & Kalan Kontör Sorgulama

<?php

use Uyumsoft\UyumsoftClient;
use Uyumsoft\UyumsoftException;

require_once 'vendor/autoload.php';

$client = new UyumsoftClient([
    'username'  => 'YOUR_UYUMSOFT_USERNAME',
    'password'  => 'YOUR_UYUMSOFT_PASSWORD',
    'test_mode' => false, // Canlı ortam için false, test için true
    'verify_ssl'=> true,
    'timeout'   => 45
]);

try {
    // 1. Bağlantı Testi
    $conn = $client->testConnection();
    echo "Bağlantı: " . ($conn['success'] ? 'Başarılı' : 'Hatalı') . "\n";

    // 2. Firma Profil Bilgileri
    $profile = $client->getCompanyProfile();
    echo "Unvan: " . $profile['name'] . " | VKN: " . $profile['tax_no'] . "\n";

    // 3. Kalan Kontör Bilgisi
    $credit = $client->getCustomerCreditInfo();
    print_r($credit);

} catch (UyumsoftException $e) {
    echo "Hata: " . $e->getMessage();
}

2. Alıcı Mükellef Sorgulama & Posta Kutusu Tespiti

Alıcıya fatura kesmeden önce e-Fatura mükellefi olup olmadığını kontrol ederek belge tipini belirleyebilirsiniz:

<?php
use Uyumsoft\UyumsoftClient;

$client = new UyumsoftClient([/* config */]);
$vknTckn = '1234567890';

// 1. E-Fatura kullanıcısı mı?
$isEInvoice = $client->isEInvoiceUser($vknTckn);

if ($isEInvoice) {
    echo "Alıcı e-Fatura mükellefidir.\n";
    
    // 2. Posta kutusu (PK/GB) etiketlerini çekme
    $aliases = $client->getUserAliases($vknTckn);
    $selectedAlias = $aliases[0]['Alias'] ?? 'defaultpk';
    echo "Kullanılacak Etiket: " . $selectedAlias . "\n";
} else {
    echo "Alıcı e-Fatura mükellefi değildir. e-Arşiv faturası düzenlenecektir.\n";
}

// 3. VKN/TCKN numarasından resmî unvan ve adres çekme
$addressInfo = $client->tryToGetAddressFromVknTckn($vknTckn);
print_r($addressInfo);

3. E-Ticaret İnternet Satışlı e-Arşiv Faturası Oluşturma ve Gönderme

İnternet satış bilgileri, kargo bilgileri, satır indirimleri ve genel sipariş iskontosu içeren tam teşekküllü e-Arşiv örneği:

<?php

use Uyumsoft\UyumsoftClient;
use Uyumsoft\InvoiceData;
use Uyumsoft\InvoiceItemData;
use Uyumsoft\InvoicePartyData;
use Uyumsoft\InternetSalesInfoData;
use Uyumsoft\UblInvoiceBuilder;

$client = new UyumsoftClient([/* config */]);

// 1. Satıcı Bilgileri
$supplier = new InvoicePartyData(
    name: 'ABC E-Ticaret ve Bilişim Anonim Şirketi',
    taxNo: '1234567890',
    address: 'Büyükdere Cad. No:100 Kat:5',
    city: 'İstanbul',
    district: 'Şişli',
    taxOffice: 'Mecidiyeköy',
    email: 'fatura@example.com',
    phone: '02125550000'
);

// 2. Alıcı Bilgileri (Nihai tüketici için TCKN=11111111111 kullanılabilir)
$customer = new InvoicePartyData(
    name: 'Ahmet Yılmaz',
    taxNo: '11111111111',
    address: 'Atatürk Caddesi No:15 Daire:3',
    city: 'Ankara',
    district: 'Çankaya',
    email: 'ahmet@example.com',
    phone: '05551234567'
);

// 3. Fatura Başlığı
$invoice = new InvoiceData(
    supplier: $supplier,
    customer: $customer,
    documentType: 'eArchive',
    invoiceNumber: InvoiceData::generateMockNumber('DKC') // Örn: DKC2026000000001
);

$invoice->localDocumentId = 'SIPARIS-10025'; // Kendi sipariş ID'niz

// 4. Kalemleri Ekleme
$invoice->addItem(new InvoiceItemData(
    name: 'Pamuklu Erkek Gömlek Mavi - L',
    sku: 'GML-BLU-L',
    quantity: 2.0,
    unitPrice: 450.00, // KDV Dahil Brüt Birim Fiyat
    vatRate: 10.0,     // %10 KDV
    discount: 50.00    // Kalem İndirimi
));

// 5. Kargo Bedeli Ekleme
$invoice->setShipping(amount: 89.90, vatRate: 20.0, name: 'Kargo Hizmeti');

// 6. Genel Sipariş İskontosu
$invoice->orderDiscount = 50.00;

// 7. GİB İnternet Satış ve Kargo Bilgileri (Zorunlu)
$invoice->setInternetSales(new InternetSalesInfoData(
    webAddress: 'https://www.example.com',
    paymentMidierName: 'PayTR',
    paymentType: 'KREDIKARTI/BANKAKARTI',
    paymentDate: new DateTimeImmutable(),
    sendDate: new DateTimeImmutable('+1 day'),
    carrierTaxNo: '7321640262',
    carrierName: 'Sürat Kargo Lojistik Dağıtım A.Ş.'
));

// 8. UBL-TR Derleme & Doğrulama
$builder = new UblInvoiceBuilder();
$built = $builder->build($invoice);

$client->validateInvoice($built['xml']);

// 9. Gönderim
$response = $client->sendInvoice($invoice, $built['xml']);

echo "Fatura Gönderildi!\n";
echo "Fatura No: " . ($response['number'] ?? $invoice->invoiceNumber) . "\n";
echo "Uyumsoft ID: " . $response['id'] . "\n";
echo "Durum: " . $response['status'] . "\n";

4. Kurumsal e-Fatura Gönderme (B2B)

Kurumsal firmalara kesilen ticari veya temel e-fatura akışı:

<?php
use Uyumsoft\UyumsoftClient;
use Uyumsoft\InvoiceData;
use Uyumsoft\InvoiceItemData;
use Uyumsoft\InvoicePartyData;

$client = new UyumsoftClient([/* config */]);

$receiverVkn = '9876543210';
$aliases = $client->getUserAliases($receiverVkn);

$supplier = new InvoicePartyData('Satıcı A.Ş.', '1234567890', 'Adres...', 'İstanbul');
$customer = new InvoicePartyData(
    name: 'Alıcı Holding A.Ş.',
    taxNo: $receiverVkn,
    address: 'Adres...',
    city: 'Bursa',
    taxOffice: 'Nilüfer',
    alias: $aliases[0]['Alias'] ?? 'defaultpk'
);

$invoice = new InvoiceData($supplier, $customer, documentType: 'eInvoice');
$invoice->profileId = 'TICARIFATURA'; // veya 'TEMELFATURA'

$invoice->addItem(new InvoiceItemData('Sunucu Kabini 42U', 'SRV-01', 1, 15000.0, 20.0));

$result = $client->sendInvoice($invoice);
echo "e-Fatura İletildi. Belge ID: " . $result['id'] . "\n";

5. Fatura Durumu İzleme & Resmî PDF İndirme

<?php
use Uyumsoft\UyumsoftClient;

$client = new UyumsoftClient([/* config */]);
$invoiceId = '3fa85f64-5717-4562-b3fc-2c963f66afa6';

// 1. Giden Fatura Durumu
$status = $client->queryOutboxInvoiceStatus($invoiceId);
echo "Durum: " . $status['status'] . " | Fatura No: " . $status['number'] . "\n";
// Olası Durumlar: Queued, Processing, SentToGib, Approved, Declined, Error, Canceled

// 2. Resmî Mühürlü PDF İndirme
$pdfBinary = $client->getOutboxInvoicePdf($invoiceId);
file_put_contents('fatura.pdf', $pdfBinary);
echo "Resmî PDF kaydedildi.\n";

6. e-Arşiv Fatura İptali & Kurtarma

<?php
use Uyumsoft\UyumsoftClient;

$client = new UyumsoftClient([/* config */]);
$invoiceId = '3fa85f64-5717-4562-b3fc-2c963f66afa6';

// 1. İptal Etme
$res = $client->cancelEArchiveInvoice(
    invoiceId: $invoiceId,
    reason: 'Müşteri siparişi kargolanmadan iptal etti.'
);
echo "İptal Sonucu: " . $res['message'] . "\n";

// 2. Yanlışlıkla yapılan iptali kurtarma
// $client->recoverEArchiveCancel($invoiceId);

7. Gelen Faturaları Okuma & Kabul / Ret Yanıtı Gönderme

<?php
use Uyumsoft\UyumsoftClient;

$client = new UyumsoftClient([/* config */]);

// Son 7 günün gelen faturaları
$inbox = $client->getInboxInvoiceList(new DateTimeImmutable('-7 days'), new DateTimeImmutable());

// Gelen ticari faturaya Uygulama Yanıtı (RED / KABUL) verme:
$client->sendDocumentResponse(
    invoiceId: 'gelen-fatura-uuid',
    responseType: 'RED',
    reason: 'Faturadaki birim fiyat sipariş şartlarına uymamaktadır.'
);

8. Mükerrer Fatura Önleyici Ağ Kurtarma Akışı (Idempotency Recovery)

Gerçek dünyada ağ kopmalarında mükerrer fatura kesilmesini engelleyen örnek akış:

<?php
use Uyumsoft\UyumsoftClient;
use Uyumsoft\UyumsoftException;

function sendSafely(UyumsoftClient $client, $invoice, $builder) {
    try {
        $built = $builder->build($invoice);
        return $client->sendInvoice($invoice, $built['xml']);
    } catch (UyumsoftException $e) {
        // Ağ zaman aşımında önce Uyumsoft'ta fatura oluşmuş mu sorgula
        $check = $client->queryOutboxInvoiceStatus($invoice->uuid);
        if (!empty($check['status']) && !in_array($check['status'], ['Error', 'NotFound'])) {
            // Fatura zaten oluşmuş! İkinci kez fatura kesilmedi.
            return ['recovered' => true, 'id' => $check['id'], 'status' => $check['status']];
        }
        throw $e;
    }
}

📋 Uyumsoft WSDL 64 Web Servis Operasyon Referansı

Uyumsoft BasicHttpBinding_IIntegration servisi üzerinde keşfedilen tüm operasyonlar ve bu SDK'daki karşılıkları:

Kategori WSDL Operasyon Adı SDK Metodu / Destek Açıklama
Sistem & Kimlik TestConnection $client->testConnection() Servis erişilebilirliğini test eder.
WhoAmI $client->whoAmI() Giriş yapan kullanıcının kimlik detayları.
GetCustomerCreditInfo $client->getCustomerCreditInfo() Kalan e-Dönüşüm kontör/bakiye bilgisi.
GetSystemDate $client->getSystemDate() Sunucu saat ve tarihini döndürür.
GetAccessToken / Refresh $client->rawCall(...) OAuth token yönetimi (REST/SOAP köprüleri).
Mükellef & Alıcı IsEInvoiceUser $client->isEInvoiceUser($vkn) VKN/TCKN e-fatura mükellef kontrolü.
GetUserAliasses $client->getUserAliases($vkn) Posta kutusu (GB/PK) etiket listesi.
TryToGetAddressFromVknTckn $client->tryToGetAddressFromVknTckn($vkn) VKN'den resmî unvan ve adres çözümleme.
FilterEInvoiceUsers $client->filterEInvoiceUsers($list) Toplu VKN listesini mükelleflere göre filtreler.
GetSystemUsersCompressedList $client->rawCall(...) Tüm mükellef listesini sıkıştırılmış dosya olarak çeker.
Fatura Gönderimi SendInvoice $client->sendInvoice($invoice) e-Fatura / e-Arşiv gönderimi.
ValidateInvoice $client->validateInvoice($xml) UBL-TR şematron ve XML doğrulaması.
SaveAsDraft $client->saveAsDraft($invoice) Portalda taslak olarak saklar.
SendDraft $client->sendDraft($id) Taslak faturayı gönderime alır.
CancelDraft $client->cancelDraft($id) Taslak faturayı siler.
CompressedSendInvoice $client->rawCall(...) Büyük faturaları GZip ile sıkıştırarak iletir.
SubmitInvoicesBatch $client->rawCall(...) Çoklu toplu fatura gönderimi.
RetrySendInvoices $client->rawCall(...) Hatalı faturaların yeniden denenmesi.
Giden Faturalar QueryOutboxInvoiceStatus $client->queryOutboxInvoiceStatus($id) Fatura durumunu sorgular (Approved, Queued vb.).
GetOutboxInvoiceStatusWithLogs $client->getOutboxInvoiceStatusWithLogs($id) Detaylı GİB ve sistem hareket geçmişi logları.
GetOutboxInvoicePdf $client->getOutboxInvoicePdf($id) Resmî mühürlü PDF belgesini indirir.
GetOutboxInvoiceView $client->getOutboxInvoiceView($id) Faturanın HTML görsel önizlemesini çeker.
GetOutboxInvoice $client->getOutboxInvoice($id) Giden faturanın UBL XML'ini çeker.
GetOutboxInvoiceList $client->getOutboxInvoiceList(...) Tarih aralığında giden faturaları listeler.
GenerateDocumentUrl $client->rawCall(...) Müşteri için doğrulanabilir belge linki üretir.
e-Arşiv Özel CancelEArchiveInvoice $client->cancelEArchiveInvoice($id) e-Arşiv faturasını resmî olarak iptal eder.
RecoverEArchiveCancel $client->recoverEArchiveCancel($id) İptal edilen e-Arşivi kurtarır.
Gelen Faturalar GetInboxInvoiceList $client->getInboxInvoiceList(...) Gelen e-faturaları listeler.
GetInboxInvoicePdf $client->getInboxInvoicePdf($id) Gelen faturanın PDF'ini indirir.
GetInboxInvoice $client->getInboxInvoice($id) Gelen faturanın UBL XML'ini indirir.
SendDocumentResponse $client->sendDocumentResponse(...) Ticari faturaya KABUL veya RED uygulama yanıtı.
SetInvoicesTaken $client->rawCall(...) Faturaları alındı olarak işaretler.
İrsaliye & Diğer QueueInvoiceFromDespatches $client->rawCall(...) İrsaliyeden faturalaştırma kuyruğu.
GetXsltView / SetXsltView $client->rawCall(...) XSLT görsel şablon yönetimi.

Note

Yukarıdaki tabloda yer alan veya yer almayan tüm 64 web servis fonksiyonunu $client->rawCall($action, $body) metoduyla doğrudan çağırabilirsiniz.


🔒 Güvenlik Notları ve En İyi Uygulamalar

  1. XXE (XML External Entity) Koruması:
    • SDK, sunucudan dönen yanıtları ayrıştırmadan önce taranır. <!DOCTYPE veya <!ENTITY ifadeleri tespit edilirse işlem anında durdurulur ve libxml_disable_entity_loader(true) uygulanır.
  2. XML Bomb (Billion Laughs) Savunması:
    • Bellek tüketim saldırılarına (DoS) karşı DTD ve dış varlık çözümlemesi engellenmiştir.
  3. SSL Doğrulaması:
    • Canlı ortamda verify_ssl => true parametresi zorunlu tutulmalıdır. Devre dışı bırakıldığında SDK sistem loglarına uyarı yazar.
  4. Kimlik Bilgisi Güvenliği:
    • Uyumsoft API şifrenizi asla Git depolarına (versiyon kontrolüne) göndermeyiniz. .env ortam değişkenleri veya gizli kasa (vault) sistemlerinde muhafaza ediniz.

📜 Lisans

Bu proje MIT Lisansı ile lisanslanmıştır. Kişisel veya ticari projelerinizde serbestçe kullanabilir, uyarlayabilir ve dağıtabilirsiniz.

About

Zero-dependency, cURL-based PHP SDK for Uyumsoft E-Dönüşüm (e-Fatura, e-Arşiv, UBL-TR 2.1) SOAP API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages