MEDULA, Sosyal Güvenlik Kurumu'nun sağlık ödeme sistemidir; Türkiye'de SGK ile sözleşmeli her sağlık tesisi, verdiği hizmetin bedelini ancak MEDULA üzerinden talep edebilir. Entegrasyon teknik olarak SOAP web servisleri üzerinden yapılır, kimlik doğrulama HTTP Basic Authentication ile her istekte tekrarlanır ve süreç üç aşamadan oluşur: Hasta Kabul (provizyon) → Hizmet Kayıt → Fatura Kayıt. Bu rehber, bu üç sürecin metotlarını, dönen veri yapılarını, hata semantiğini ve sahada en çok zaman kaybettiren tasarım hatalarını anlatıyor.
Bu yazıdaki metot adları, alan adları ve kod listeleri SGK'nın yayımladığı "SYDB / Medula Web Servisleri Kullanım Kılavuzu — MEDULA HASTANE" dokümanından alınmıştır. Kılavuz sürümlenir; üretime çıkmadan önce SGK'dan güncel sürümü teyit edin.
MEDULA'nın Yeri: Sağlık Bakanlığı Değil, SGK
Sahada en sık karışan nokta bu olduğu için baştan netleştirelim. Bir hastane yazılımının iki ayrı kuruma karşı iki ayrı teknik yükümlülüğü vardır:
| USS / e-Nabız | MEDULA | |
|---|---|---|
| Kurum | Sağlık Bakanlığı | Sosyal Güvenlik Kurumu (SGK) |
| Amaç | Klinik verinin merkezî toplanması | Hizmetin ödenmesi |
| Protokol | Tek SOAP metodu, string XML paket | Süreç başına ayrı WSDL, tipli DVO nesneleri |
| Ön koşul | SBYS tescili (KTS) | SGK sözleşmesi + tesis kodu + tesis kullanıcı/şifre |
İki entegrasyon aynı projede yürütülür ama teknik olarak hiçbir şey paylaşmazlar. USS tarafını ayrıntılı ele aldığımız yazı: HBYS Nedir? Hastane Bilgi Yönetim Sistemi Mimarisi, USS Entegrasyonu ve SBYS Tescili.
Servis Adresleri ve Kimlik Doğrulama
MEDULA Hastane servisleri süreç bazında ayrılmıştır. Üretim ve test ortamları farklı alan adlarındadır:
# Uretim (production)
https://medula.sgk.gov.tr/medula/hastane/hastaKabulIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/hizmetKayitIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/faturaKayitIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/raporIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/sevkIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/takipFormuIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/taahhutIslemleriWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/yardimciIslemlerWS?wsdl
https://medula.sgk.gov.tr/medula/hastane/EvrakDokumanIslemleriServiceWS?wsdl
# Test
https://sgkt.sgk.gov.tr/medula/hastane/hastaKabulIslemleriWS?wsdl
https://sgkt.sgk.gov.tr/medula/hastane/faturaKayitIslemleriWS?wsdl
# ... ayni yol yapisi, farkli alan adi
Kimlik doğrulama kılavuzda net biçimde tanımlanmıştır: "Web servislerinde HTTP Basic Authentication yöntemi kullanılmaktadır. Bunun için web servis isteklerinde (request), tesis kullanıcı adı ve şifresi HTTP Header içinde GSS sunucusuna gönderilmelidir. Web servisleri teknolojisi ile oturum (session) bilgisini muhafaza etmenin henüz standart bir yolu olmadığı için, kullanıcı adı ve şifrenin her SOAP isteminde (request) gönderilmesi gerekmektedir."
Pratik sonuçları:
- Oturum yok. Token saklama, yenileme, süre dolumu diye bir mekanizma yoktur. Her çağrı kendi başına yetkilidir.
- Kimlik bilgisi HTTP katmanındadır, SOAP gövdesinde değil. WS-Security / UsernameToken aramayın.
- Tesis kullanıcısı ≠ yönetici şifresi. Kılavuz ikisini ayırır: tesis kullanıcısı web servisleri içindir; yönetici şifresi başhekim/yöneticinin web uygulamasında dönem sonlandırma, evrak üst yazısı oluşturma ve ödeme takibi için kullandığı ayrı bir kimliktir. Entegrasyon kodunda yönetici şifresi kullanılmaz.
<?php
// PHP SoapClient ile HTTP Basic - kimlik HTTP basliginda tasinir
$client = new SoapClient(
'https://sgkt.sgk.gov.tr/medula/hastane/hastaKabulIslemleriWS?wsdl',
[
'login' => $tesisKullaniciAdi,
'password' => $tesisSifre,
'soap_version' => SOAP_1_1,
'trace' => true, // ham istek/yanit icin sart
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_DISK,
'connection_timeout' => 20,
]
);
Boş gönderilen alanlar sessiz hata üretir
SGK'nın kılavuzunda özellikle vurguladığı bir tuzak var: ilkel (primitive) veri tiplerine sahip alanların istek mesajında varsayılan değerleriyle bulunması gerekir. Bir ilkel tip alanı hiç gönderilmez veya boş gönderilirse istek başarısız olur. PHP, Java veya .NET tarafında "null ise alanı hiç ekleme" şeklinde bir serileştirme optimizasyonu yapıyorsanız, bu davranış MEDULA'da hataya dönüşür. İstek nesnenizi kurarken zorunlu ilkel alanları açıkça doldurun.
Süreç 1 — Hasta Kabul: Provizyon Alma
Süreç, kişinin sağlık hizmet sunucusuna başvurmasıyla başlar. Kılavuzun tanımıyla bu aşamada kişinin müstehaklık sorgulaması ve tesisin SGK ile anlaşmalı olup olmadığı kontrol edilir; sonuçta hasta için bir HastaBaşvuruNo ve bununla ilişkili bir takip numarası üretilir. Tedavi boyunca verilen tüm hizmetler bu takip numarası üzerinden izlenir.
Hasta Kabul metotları
HastaKabul— provizyon alır, takip üretirHastaKabulKimlikDogrulama— kimlik doğrulama (biyometrik dahil) akışıHastaKabulOku— mevcut kabul kaydını okurHastaKabulIptal— kabulü iptal ederHastaCikisKayit/HastaCikisIptal— yatan hasta çıkışıHastaYatisOku,BasvuruAltindakiTakipleriOkuSevkBildir,UpdateTedaviTipi,UpdateProvizyonTipi
HastaKabul girdisi: ProvizyonGirisDVO
En kritik alanlar ve kılavuzdaki kod listeleri:
| Alan | Tip | Açıklama |
|---|---|---|
saglikTesisKodu |
Integer | Tesisin SGK tarafından verilmiş kodu. Zorunlu. |
hastaTCKimlikNo |
String(11) | Takip No dolu ise zorunlu değil — takipteki bilgi esas alınır. |
sigortaliTuru |
String(1) | 1: Çalışan · 2: Emekli · 3: SSK Kurum Personeli · 4: Diğer |
devredilenKurum |
String(1..2) | 1: SSK · 2: Bağkur · 3: Emekli Sandığı · 4: Yeşil Kart · 12: SGK · 99: Yurtdışı sigortalılar — ve 20'den fazla özel statü kodu |
bransKodu |
String(4) | Hizmetin verildiği branş |
provizyonTarihi |
String(10) | dd.mm.yyyy formatında. ISO 8601 değil. |
provizyonTipi |
String(1) | N: Normal · A: Acil · I: İş kazası · T: Trafik kazası · V: Adli vaka · M: Meslek hastalığı · K: Kurum sevki · L: Analık · D: Doğal afet … |
takipTipi |
String(1) | N: Normal · E: Eşlik eden hastalık · U: Uzayan yatış · K: Komplikasyon · Y: Yoğun bakım · T: Tanı amaçlı günübirlik … |
takipNo |
String | Mevcut bir takipten bağlı takip üretmek için. İlk takipte boş gönderilir. |
hastaTelefon, hastaAdres |
String | İlk takiplerde zorunlu. Telefon 3121234567 biçiminde. |
vakaTarihi, plakaNo |
String | Trafik kazası, adli vaka ve iş kazası provizyonlarında gönderilir. |
HastaKabul çıktısı: ProvizyonCevapDVO
Dönen yapı ve semantiği — burası entegrasyonun kalbidir:
ProvizyonCevapDVO {
sonucKodu : String(4) // "0000" ise HATASIZ. Farkli ise islem HATALI.
sonucMesaji : String // hata sebebi burada
takipNo : String // uretilen takip numarasi
hastaBasvuruNo : String // tedavi boyunca tum takipleri baglar
hastaBilgileri : HastaBilgileriDVO
sigortaliAdliGecmisi : SigortaliAdliGecmisDVO[]
}
Sahada en çok hataya yol açan iki nokta burada:
sonucKodubir string'dir, sayı değil."0000"ile0aynı şey değildir.if ($cevap->sonucKodu == 0)yazan kod, PHP'nin gevşek karşılaştırmasıyla bazı hata kodlarını da "başarılı" sayabilir. Katı karşılaştırma kullanın:$cevap->sonucKodu === '0000'.- SOAP çağrısının başarılı dönmesi, işlemin başarılı olduğu anlamına gelmez. HTTP 200 + geçerli SOAP zarfı alırsınız ama
sonucKoduhata olabilir. İş kuralı hatası ile taşıma hatası iki ayrı yoldur ve ikisini de ele almalısınız.
<?php
final class ProvizyonSonucu
{
public function __construct(
public readonly bool $basarili,
public readonly string $sonucKodu,
public readonly string $sonucMesaji,
public readonly ?string $takipNo = null,
public readonly ?string $hastaBasvuruNo = null,
) {}
}
public function provizyonAl(array $giris): ProvizyonSonucu
{
// 1) Tasima katmani hatasi (aglaysal / kimlik / servis kapali)
try {
$cevap = $this->client->HastaKabul(['provizyonGirisDVO' => $giris]);
} catch (SoapFault $e) {
$this->hamKaydet($giris, $this->client);
throw new MedulaUlasilamadiException($e->getMessage(), previous: $e);
}
$this->hamKaydet($giris, $this->client); // her zaman ham istek/yanit sakla
// 2) Is kurali hatasi - SOAP basarili ama islem hatali olabilir
$kod = (string) ($cevap->sonucKodu ?? '');
if ($kod !== '0000') {
return new ProvizyonSonucu(
basarili: false,
sonucKodu: $kod,
sonucMesaji: (string) ($cevap->sonucMesaji ?? 'Bilinmeyen hata'),
);
}
return new ProvizyonSonucu(
basarili: true,
sonucKodu: $kod,
sonucMesaji: (string) ($cevap->sonucMesaji ?? ''),
takipNo: (string) $cevap->takipNo,
hastaBasvuruNo: (string) $cevap->hastaBasvuruNo,
);
}
Takip No ile HastaBaşvuruNo arasındaki ilişki
Bu ayrımı veri modelinize doğru yansıtmak, projenin ilerleyen aşamalarında en çok işinize yarayacak şeydir:
- HastaBaşvuruNo: hastanın tesise o tedavi için ilk başvurusunda üretilir. Tedavi boyunca üretilen tüm takipler bu numarayla ilişkilidir.
- TakipNo: her branş/ilişki için ayrı üretilir. Aynı başvuru altında aynı veya farklı branşlarda birden fazla takip açılabilir ve bunlar birbirine bağlıdır.
Yani ilişki tekil değil, 1 HastaBaşvuruNo → N TakipNo şeklindedir. Hizmetler takip numarasına, faturalama ise başvuru numarasına bağlanır. Veri modelinde bunu tek tabloya sıkıştıran ekipler faturalama aşamasında baştan yazmak zorunda kalır.
Süreç 2 — Hizmet Kayıt
Provizyon alındıktan sonra tedavi boyunca verilen her hizmet bu süreçte kaydedilir.
HizmetKayit— hizmetleri takip numarasına bağlarHizmetKaydiOku— kaydedilmiş hizmetleri okurHizmetKaydiIptal— düzeltme/silmeutsKullanimKesinlestirme,utsKullanimKesinlestirmeSorgu,utsKullanimKesinlestirmeIptal— Ürün Takip Sistemi (tıbbi malzeme barkodu) kesinleştirme
Ana metotlar için düzeltme ve silme fonksiyonlarının bulunması tesadüf değil: kılavuz bunu açıkça "süreçlerin işletilmesinde yapılan hataların sağlık tesisleri tarafından düzeltilebilmesi amacıyla" eklendiğini söyler. Entegrasyonunuz bu düzeltme yollarını baştan desteklemelidir. Sadece "kaydet" yazan bir entegrasyon, ilk yanlış girişte operasyonu kilitler.
Süreç 3 — Fatura Kayıt
Kılavuzun tanımı önemli bir mimari kısıt içerir: "Hasta Başvuru numarasına bağlı olan o tedavi boyunca alınmış faturalanmamış tüm ilişkili takipler faturalamaya birlikte gönderilecektir." Yani faturalama birimi takip değil, başvurudur.
FaturaKayit
FaturaGirisDVO {
saglikTesisKodu : Integer // zorunlu
faturaTarihi : String(10) // "dd.mm.yyyy"
hastaBasvuruNo : String // zorunlu - takipNo DEGIL
faturaRefNo : String(20) // tesisin kendi referans numarasi
hizmetDetaylari : HizmetDetayDVO[]
trafikKazasiOdemeYuzdesi : Integer
ilaveUcret : Double // hastadan alinan ilave fark ucreti
}
FaturaCevapDVO {
sonucKodu : String(4) // "0000" = hatasiz
sonucMesaji : String
faturaTeslimNo : String // bundan sonraki tum fatura islemlerinde kullanilir
}
Dikkat edilecek üç kural:
- Yatış kapatılmadan faturalanamaz. Kılavuz açıkça belirtir: hastanın yatışı varsa, yatış kapatılmadan o tedaviyle ilişkili hiçbir takip faturalanamaz.
- Faturalanmış yatış aralığına geriye dönük takip verilemez. Aynı veya farklı tesiste olsun fark etmez. Bu, "önce faturalayalım, eksiği sonra ekleriz" alışkanlığını imkânsız kılar.
faturaRefNosizin ürettiğiniz anahtardır — idempotency anahtarınız olarak kullanın. Ağ kesintisinde yanıtı alamadıysanız, aynı referansla tekrar denemeden önceFaturaOkuile durumu sorgulayın. Kör tekrar, çift fatura üretir.
Fiyatlandırma çevrimiçi yapılır: gönderilen tüm işlem ve takipler değerlendirilir, tedavi için bir fatura kaydı oluşturulur ve toplam fatura fiyatı tesise döndürülür. Yani faturanın tutarını siz hesaplamazsınız — SGK hesaplar ve size bildirir. Kendi hesabınızla SGK'nın hesabı arasındaki farkı izlemek, döner sermaye ekibinin en çok ihtiyaç duyduğu rapordur.
Üretime Çıkmadan Önce: 7 Maddelik Kontrol Listesi
| # | Kontrol | Neden |
|---|---|---|
| 1 | sonucKodu karşılaştırması katı (=== '0000') | Gevşek karşılaştırma hatalı işlemi başarılı sayabilir |
| 2 | Ham SOAP istek/yanıt saklanıyor | Hata mesajları bağlamsızdır; geriye dönük inceleme başka türlü mümkün değil |
| 3 | Tarihler dd.mm.yyyy | ISO format reddedilir; Carbon::format('d.m.Y') tek noktada yapılsın |
| 4 | Zorunlu ilkel alanlar açıkça dolduruluyor | Boş/eksik ilkel alan isteği başarısız kılar |
| 5 | Test ve üretim adresleri konfigürasyonda | sgkt ve medula alan adları koda gömülmemeli |
| 6 | İptal/düzeltme metotları da uygulanmış | Yalnız "kaydet" yazan entegrasyon ilk hatada operasyonu kilitler |
| 7 | faturaRefNo tekil ve idempotency anahtarı | Kör tekrar denemesi çift fatura üretir |
Mimari: MEDULA'yı Nereye Koymalı?
Önerdiğimiz yerleşim, MEDULA'yı uygulamanın kenarına almaktır:
- Adaptör katmanı. SOAP istemcisi tek bir sınıfta kapsüllenir. Uygulamanın geri kalanı
SoapClientgörmez,ProvizyonSonucugibi kendi tiplerinizi görür. - Senkron çağrı yalnızca provizyonda. Provizyon, hasta karşınızda dururken alınır; kuyruğa atılamaz. Ama hizmet kaydı ve faturalama kuyrukla yapılır.
- Durum makinesi. Her başvuru için
taslak → provizyon_alindi → hizmetler_kaydedildi → faturalandi → iptalgibi açık bir durum alanı tutun. "Hangi kayıt hangi aşamada?" sorusuna SQL ile cevap verilebilmeli. - Yeniden deneme politikası. Taşıma hatalarında üstel geri çekilmeyle (exponential backoff) tekrar denenir; iş kuralı hatalarında tekrar denenmez, operasyona düşer.
- Gözlemlenebilirlik.
sonucKodubazında sayaç tutun. Hangi hata kodunun hangi branşta arttığını görmek, mevzuat değişikliklerini kılavuz güncellemesinden önce fark etmenizi sağlar.
Bu deseni benzer regüle entegrasyonlarda da kullanıyoruz; e-Fatura tarafındaki karşılığını GİB e-Fatura ve e-Arşiv API entegrasyonu rehberimizde anlattık.
Süre ve Maliyet: Gerçekçi Aralıklar
MEDULA entegrasyonunun büyüklüğünü belirleyen şey metot sayısı değil, kapsanan senaryo sayısıdır. Yalnızca normal poliklinik provizyonu ile yatan hasta, yoğun bakım, komplikasyon, sevk, adli vaka ve UTS malzeme kesinleştirmesini kapsayan bir entegrasyon arasında kat kat fark vardır.
ininia'da tüm yazılım geliştirme işleri 300–400 USD/adam-gün bandında, adam-gün dökümüyle fiyatlanır. Bu tür bir entegrasyonda dökümü şu başlıklara ayırmanızı öneriyoruz (kendi teklif hazırlığınızda da işinize yarar):
- Adaptör + kimlik doğrulama + ham log altyapısı
- Hasta Kabul süreci (senaryo başına ayrı kalem)
- Hizmet Kayıt + UTS
- Fatura Kayıt + iptal/düzeltme yolları
- Durum makinesi, kuyruk, yeniden deneme
- Test ortamında senaryo koşumu ve mutabakat
Kendi kapsamınız için aralık görmek isterseniz proje fiyat hesaplama aracımızı kullanabilirsiniz.
Sıkça Sorulan Sorular
MEDULA entegrasyonu için hangi izinler gerekir?
Sağlık tesisinin SGK ile sözleşmeli olması, tesis kodunun tanımlı olması ve tesise ait web servis kullanıcı adı/şifresinin verilmiş olması gerekir. Bu, Sağlık Bakanlığı'nın SBYS tescil sürecinden ayrı bir süreçtir.
MEDULA REST API sunuyor mu?
Hastane servisleri SOAP tabanlıdır ve WSDL üzerinden tanımlanır. Modern bir REST istemcisi bekleyerek işe başlamayın; SOAP istemcisi kurmayı ve WSDL'den kod üretmeyi planlayın.
sonucKodu "0000" dışında bir değer döndüğünde ne yapmalıyım?
İşlem hatalıdır ve sonucMesaji alanı sebebi taşır. Bu bir iş kuralı hatasıdır — otomatik yeniden deneme yapılmamalı, kayıt operasyon ekibine düşmelidir. Yalnızca ağ/taşıma hatalarında tekrar denenir.
Test ortamı nasıl alınır?
Test ortamı ayrı alan adı üzerinde çalışır (sgkt.sgk.gov.tr) ve ayrı kimlik bilgisi gerektirir. Erişim SGK üzerinden tesis adına açılır. Tüm senaryoları — özellikle iptal, düzeltme ve yatan hasta akışlarını — test ortamında koşmadan üretime çıkmayın.
Provizyon alırken hastanın telefonu ve adresi zorunlu mu?
Kılavuza göre hastaTelefon ve hastaAdres alanları ilk takiplerde zorunludur. Telefon 3121234567 biçiminde, on haneli ve ayraçsız gönderilir.
Bir hasta için kaç takip açılabilir?
Aynı HastaBaşvuruNo altında, tedavi boyunca aynı veya farklı branşlarda birden fazla takip açılabilir ve bunlar birbiriyle ilişkilidir. Verilen hizmetler takip numaraları üzerinden izlenir; faturalama ise başvuru numarası üzerinden yapılır.
MEDULA ile e-Nabız aynı veriyi mi alıyor?
Hayır. e-Nabız/USS klinik veriyi toplar ve vatandaşa gösterir; MEDULA ise hizmetin SGK tarafından ödenmesini sağlar. İki sistem ayrı kurumlara aittir, ayrı protokoller kullanır ve birinden diğerine veri akmaz — ikisine de ayrı ayrı gönderim yaparsınız.
Sonuç
MEDULA entegrasyonunu zorlaştıran şey SOAP değil; onlarca kod listesi, senaryo bazlı zorunluluk kuralları ve "HTTP 200 ama işlem hatalı" ikiliğidir. Bu üçünü baştan doğru modelleyen bir entegrasyon — katı sonucKodu kontrolü, ham istek/yanıt saklama, başvuru–takip ilişkisinin doğru veri modeli ve iptal/düzeltme yollarının ilk günden uygulanması — yıllarca sessizce çalışır. Bunları sonraya bırakan entegrasyon ise döner sermaye ekibinin her ay elle düzelttiği bir yüke dönüşür.
ininia olarak sağlık alanında MEDULA ve USS entegrasyonları, HBYS'ye bağlanan yan uygulamalar ve entegrasyon ara katmanları geliştiriyoruz. Yaklaşımımızı sağlık ve medikal yazılım sayfasında görebilir, kendi projeniz için iletişim sayfasından yazabilirsiniz.
Kaynak: SGK "SYDB / Medula Web Servisleri Kullanım Kılavuzu — MEDULA HASTANE". Metot adları, DVO alanları, kod listeleri ve sonucKodu semantiği bu kılavuzdan alınmıştır. Servis adresleri 24 Eylül 2026 tarihinde doğrulanmıştır. Kılavuz sürümlenir ve kod listeleri güncellenir; üretime çıkmadan önce SGK'dan güncel kılavuzu teyit edin.