SMS entegrasyonlarında en yaygın hata, isteğin başarısız olması değil — başarılı görünüp mesajın gitmemesidir. HTTP 200 alırsınız, kodunuz mutludur, telefon sessizdir. Cevap gövdesindeki kod okunmadıkça bu fark edilmez.
NetGSM REST uç noktası, isteği aldığını belirtmek için HTTP 200 döner; gönderimin gerçekten kabul edilip edilmediği cevabın gövdesindeki koddadır. 00 başarıdır; 30 kimlik/IP kısıtı, 40 onaysız başlık, 20 mesaj uzunluğu veya karakter hatası anlamına gelir. Entegrasyonun yalnızca HTTP durum kodunu kontrol etmesi, bu hataların tamamını görünmez kılar. Ayrıca numara 5XXXXXXXXX biçiminde olmalı (başta sıfır ya da +90 olmadan), msgheader onaylanmış bir gönderici adı olmalı ve ticari içerik için İYS kontrolü yapılmalıdır.
REST uç noktası JSON gövde ve temel kimlik doğrulama bekler. En küçük çalışan örnek:
<?php
$payload = [
'msgheader' => 'ONAYLI_BASLIK',
'encoding' => 'TR',
'messages' => [
['msg' => 'Kaydınız alınmıştır.', 'no' => '5301234567'],
],
];
$ch = curl_init('https://api.netgsm.com.tr/sms/rest/v2/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_USERPWD => NETGSM_USER . ':' . NETGSM_PASS,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
JSON_UNESCAPED_UNICODE bayrağı önemlidir; Türkçe karakterlerin \u011f gibi kaçış dizileriyle gönderilmesi bazı kurulumlarda sorun çıkarır.
Buradaki kritik nokta şudur: $http değeri neredeyse her zaman 200'dür. Gerçek sonuç gövdededir.
00 | Başarılı — gönderim kuyruğa alındı |
20 | Mesaj metni hatalı ya da karakter sınırı aşıldı |
30 | Kullanıcı adı/parola yanlış veya API erişimi IP ile kısıtlı |
40 | Gönderici başlığı onaylı değil |
50 | İYS kaynaklı engel — alıcı ticari ileti almıyor |
70 | Hatalı parametre; gövde yapısı beklenenden farklı |
30 kodu en çok zaman kaybettirenidir, çünkü kimlik bilgileri doğru olsa bile alınır. NetGSM hesabında API erişimi belirli IP adreslerine kısıtlanabilir; geliştirme makinenizden çalışan kod, sunucuya taşındığında bu yüzden durur. Sunucunun çıkış IP'sini panele eklemeden test etmek zaman kaybıdır.
Servis numarayı 5XXXXXXXXX biçiminde bekler: on hane, başta sıfır yok, ülke kodu yok. Gerçek hayatta veritabanınızdaki numaralar bu kadar düzenli olmaz — kullanıcılar boşluk, parantez, tire, +90 ve başta sıfır yazar.
Gönderimden önce tek bir normalleştirme adımı, hataların büyük kısmını ortadan kaldırır:
function netgsm_no(string $raw): ?string {
$d = preg_replace('/\D+/', '', $raw); // rakam dışını at
if (str_starts_with($d, '90')) $d = substr($d, 2);
if (str_starts_with($d, '0')) $d = substr($d, 1);
return preg_match('/^5\d{9}$/', $d) ? $d : null;
}
Geçersiz numarayı göndermek yerine null döndürüp kaydetmek, hem kredi israfını hem de teşhis edilemeyen başarısızlıkları önler.
Burada bir ödünleşme vardır. encoding değerini TR yaparsanız Türkçe harfler doğru görünür, ama mesaj Unicode olarak kodlanır ve tek SMS 160 değil 70 karaktere düşer. Uzun metin birden fazla krediye bölünür.
Alternatif, metni ASCII'ye indirgemektir: ş→s, ğ→g, ı→i, ö→o, ü→u, ç→c. 160 karakter korunur ama okunuş bozulur. Karar içeriğe bağlıdır: doğrulama kodu ve randevu hatırlatması için ASCII yeterlidir; kurumsal bilgilendirmede Türkçe karakter değerlidir.
Hangisini seçerseniz seçin, gönderimden önce karakter sayısını hesaplayın ve kaç krediye bölüneceğini kaydedin. Aksi hâlde aylık fatura beklenmedik çıkar.
Türkiye'de ticari elektronik ileti göndermek İleti Yönetim Sistemi'ne kayıtlı onaya bağlıdır. Bilgilendirme amaçlı mesajlar — sipariş durumu, randevu hatırlatma, doğrulama kodu — bu kapsamın dışındadır; kampanya ve tanıtım içerikleri ise kapsam içindedir.
Ayrımı kod tarafında da yapın: ticari gönderimlerde İYS kontrolü uygulayın, işlemsel gönderimlerde uygulamayın. İkisini tek bir fonksiyondan geçirmek, ya işlemsel mesajların gereksiz yere engellenmesine ya da ticari mesajların mevzuata aykırı gitmesine yol açar.
Üretime çıkacak bir SMS katmanının karşılaması gereken asgari maddeler:
CURLOPT_TIMEOUT) — SMS servisi yavaşladığında ödeme akışınız kilitlenmesinKayıt tutmak özellikle önemlidir. "SMS gelmedi" şikâyeti geldiğinde, dönen kodu görebiliyorsanız sorunu saniyeler içinde ayırırsınız: 00 ise mesaj operatöre teslim edilmiştir ve sorun operatör tarafındadır; 40 ise başlık onayı düşmüştür; kayıt yoksa gönderim hiç denenmemiştir.
SMS entegrasyonları basit görünür ve tam da bu yüzden özensiz yazılır. Kritik alışkanlık tek cümlede toplanır: taşıyıcının HTTP cevabı, iş sonucunu göstermez. Gövdedeki kodu okuyun, her gönderimi kaydedin, numarayı normalleştirin ve gönderimi ana akıştan ayırın. Bu dört madde, SMS kaynaklı hata ayıklama süresinin neredeyse tamamını ortadan kaldırır.
POST https://api.netgsm.com.tr/sms/rest/v2/send, temel kimlik doğrulama00 başarı5XXXXXXXXX — başta sıfır yok, +90 yokencoding: TR doğru gösterir ama sınır 160'tan 70'e düşerÇünkü HTTP durum kodu yalnızca isteğin ulaştığını söyler; gönderimin kabul edilip edilmediği cevabın gövdesindeki koddadır. 00 başarı, 30 kimlik veya IP kısıtı, 40 onaysız başlık, 20 mesaj/karakter hatası anlamına gelir. Entegrasyonunuz gövdeyi okumuyorsa bütün bu hatalar görünmez kalır.
Bu kod yalnızca kimlik hatası değil, IP kısıtı için de döner. NetGSM hesabında API erişimi belirli IP adreslerine sınırlanabilir. Geliştirme makinenizde çalışan kod sunucuya taşındığında bu yüzden durur. Sunucunun çıkış IP'sini panelde yetkili listesine ekleyin.
İçeriğe bağlı. encoding değerini TR yaptığınızda harfler doğru görünür ama mesaj Unicode'a geçer ve tek SMS sınırı 160'tan 70 karaktere düşer; uzun metin birden fazla krediye bölünür. Doğrulama kodu ve randevu hatırlatması gibi kısa işlemsel mesajlarda ASCII'ye indirgemek maliyeti belirgin biçimde düşürür.
Hayır. İYS yükümlülüğü ticari elektronik iletiler içindir. Sipariş durumu, randevu hatırlatma ve doğrulama kodu gibi işlemsel mesajlar kapsam dışıdır. Kod tarafında bu ayrımı yapmazsanız ya işlemsel mesajlarınız gereksiz engellenir ya da ticari mesajlarınız mevzuata aykırı gider.