Ana içeriğe geç

Webhook API Entegrasyonu

Webhook'lar, bir olay meydana geldiğinde veya gelirken belirtilen URL'e otomatik HTTP POST isteği göndermek için kullanılır. InsurUp platformunda 6 adet webhook aktivitesi tanımlanmış durumda olup iki çeşit event tipi bulunmaktadır:

  • Async: Event'ler bir olay gerçekleştiğinde atılır ve belirtilen API'ın sonucunu yapılan işleme etki etmez. Harici sistemlere açıktır.
  • Sync: Event'ler bir olay gerçekleşmeden önce atılır ve belirtilen API'ın sonucuna göre yapılan işleme etki edebilir. Dahili kullanım içindir. Ödeme validasyonu güzel bir örnektir.
Webhook Entity Yapısı

Her webhook bir URL, secret (opsiyonel) ve dinlenecek event listesi içerir.

Header'lar

Webhook isteklerinde aşağıdaki header'lar gönderilir:

HeaderAçıklama
x-webhook-eventTetiklenen event'in ismidir
x-webhook-idAcente panelindeki oluşturulan webhook'un tekil numarasıdır
x-webhook-deliveryTekil gönderim numarasıdır
x-webhook-signatureBu header eğer secret alanı doluysa gönderilir. Belirtilen secret ile payload SHA-256 ile şifrelenir

Event Özeti

📋 Teklif Primi (Proposal Premium) Olayları

EventTanımlayıcıTipAçıklama
ProposalPremiumReceivedproposal_premium.receivedAsyncTeklif prim hesaplaması alındığında ve başarıyla işlendiğinde tetiklenir
ProposalPremiumPurchasingproposal_premium.purchasingSyncTeklif prim satın alma süreci başlatıldığında tetiklenir (sadece dahili kullanım)
ProposalPremiumPurchasedproposal_premium.purchasedAsyncTeklif prim satın alımı başarıyla tamamlandığında tetiklenir
ProposalPremiumPurchaseFailedproposal_premium.purchase_failedAsyncTeklif prim satın alma girişimi başarısız olduğunda tetiklenir

📄 Poliçe (Policy) Olayları

EventTanımlayıcıTipAçıklama
PolicyCreatedpolicy.createdAsyncYeni bir sigorta poliçesi oluşturulup düzenlendiğinde tetiklenir
PolicyUpdatedpolicy.updatedAsyncMevcut bir sigorta poliçesi güncellendiğinde veya değiştirildiğinde tetiklenir
JSON Polimorfizm

Her event $event discriminator'ı ile JSON'da ayırt edilir. Örnek: "$event": "proposal_premium.received"


Event Detayları ve Payload Formatları

proposal_premium.received async

Bir teklif primi InsurUp'a iletildiği zaman tetiklenir.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (proposal_premium.received)
proposalIdstringTeklif ID'si
productIdintÜrün ID'si
proposalProductIdstringTeklif Ürün ID'si
productBranchProductBranchÜrün dalı (enum)
premiumsPremiumModel[]Prim detayları listesi
insuredCustomerCustomerModelSigortalı müşteri bilgileri
tempProposalDocumentUrlstring?Geçici teklif doküman URL'i
tempPreInfoDocumentUrlstring?Geçici ön bilgi doküman URL'i

Örnek Payload

{
"$event": "proposal_premium.received",
"proposalId": "673afd15f11de64fe1f2bjdb",
"productId": 40235,
"proposalProductId": "67452b1a022dec6666bf06d8",
"productBranch": "KASKO",
"premiums": [
{
"installmentNumber": 1,
"netPremium": 1243,
"grossPremium": 1243,
"commission": 0,
"exchangeRate": 1,
"currency": "TURKISH_LIRA",
"insuranceCompanyProposalNumber": "142534209"
},
{
"installmentNumber": 2,
"netPremium": 1243,
"grossPremium": 1243,
"commission": 0,
"exchangeRate": 1,
"currency": "TURKISH_LIRA",
"insuranceCompanyProposalNumber": "142534209"
}
],
"insuredCustomer": {
"$type": "individual",
"identityNumber": "12345678910",
"birthDate": "1994-01-01",
"fullName": "Müşteri ismi",
"phoneNumber": {
"number": "5432222222",
"countryCode": 90,
"areaCode": "543",
"numberWithoutAreaCode": "2222222"
},
"email": {
"value": "customer@insurup.com"
},
"city": {
"value": "34",
"text": "İSTANBUL"
},
"district": {
"value": "1823",
"text": "KÜÇÜKÇEKMECE"
}
},
"tempProposalDocumentUrl": null,
"tempPreInfoDocumentUrl": null
}

Örnek Tüzel Müşteri (Company) Payload

{
"$event": "proposal_premium.received",
"proposalId": "673afd15f11de64fe1f2bjdb",
"productId": 40235,
"proposalProductId": "67452b1a022dec6666bf06d8",
"productBranch": "KASKO",
"premiums": [...],
"insuredCustomer": {
"$type": "company",
"title": "Şirket İsmi A.Ş.",
"taxNumber": "6130782524",
"phoneNumber": {
"number": "5432222222",
"countryCode": 90,
"areaCode": "543",
"numberWithoutAreaCode": "2222222"
},
"email": {
"value": "info@sirket.com"
},
"city": {
"value": "34",
"text": "İSTANBUL"
},
"district": {
"value": "1823",
"text": "KÜÇÜKÇEKMECE"
}
},
"tempProposalDocumentUrl": null,
"tempPreInfoDocumentUrl": null
}

proposal_premium.purchasing sync

Bir teklif primini satın alınmadan önce tetiklenir. Bu event'i satın alma validasyonu olarak kullanabilirsiniz.

Dahili Kullanım

Bu event sadece dahili kullanım içindir ve harici webhook'lara gönderilmez.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (proposal_premium.purchasing)
proposalIdstringTeklif ID'si
productIdintÜrün ID'si
installmentNumberintTaksit sayısı
paymentTypePaymentOptionÖdeme tipi (enum)

Örnek Payload

{
"$event": "proposal_premium.purchasing",
"proposalId": "673afd15f11de64fe1f2bjdb",
"productId": 40235,
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD"
}

proposal_premium.purchased async

Bir teklif primini satın alma isteği başarılı olunca tetiklenir.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (proposal_premium.purchased)
proposalIdstringTeklif ID'si
policyIdstringOluşturulan poliçe ID'si
productIdintÜrün ID'si
installmentNumberintTaksit sayısı
paymentTypePaymentOptionÖdeme tipi (enum)
policyStartDateDateOnlyPoliçe başlangıç tarihi (YYYY-MM-DD)
policyEndDateDateOnlyPoliçe bitiş tarihi (YYYY-MM-DD)

Örnek Payload

{
"$event": "proposal_premium.purchased",
"proposalId": "673afd15f11de64fe1f2bjdb",
"policyId": "673b4cb4524a0a5187ddbeae",
"productId": 40235,
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD",
"policyStartDate": "2024-11-20",
"policyEndDate": "2025-11-20"
}

proposal_premium.purchase_failed async

Bir teklif primini satın alma isteği başarısız olunca tetiklenir.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (proposal_premium.purchase_failed)
proposalIdstringTeklif ID'si
productIdintÜrün ID'si
installmentNumberintTaksit sayısı
paymentTypePaymentOptionÖdeme tipi (enum)
failureReasonstring?Başarısızlık nedeni

Örnek Payload

{
"$event": "proposal_premium.purchase_failed",
"proposalId": "673afd15f11de64fe1f2bjdb",
"productId": 40235,
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD",
"failureReason": "X sigorta şirketi bilinmeyen bir nedenden dolayı poliçeleştirme isteğini reddetti"
}

policy.created async

Yeni bir sigorta poliçesi oluşturulduğunda tetiklenir. Dosya poliçe transfer, online poliçe transfer ve proje üzerinden poliçe oluşturma durumlarında çalışır.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (policy.created)
policyIdstringPoliçe ID'si
proposalIdstring?Teklif ID'si
productIdint?Ürün ID'si
installmentNumberint?Taksit sayısı
paymentTypePaymentOptionÖdeme tipi (enum)
insuranceCompanyInsuranceCompanyModelSigorta şirketi bilgileri
startDateDateOnlyPoliçe başlangıç tarihi (YYYY-MM-DD)
endDateDateOnlyPoliçe bitiş tarihi (YYYY-MM-DD)
renewalNumberbyteYenileme numarası
productBranchProductBranchÜrün dalı (enum)
insurerCustomerIdGuidSigorta ettiren müşteri ID'si
insuredCustomerIdGuidSigortalı müşteri ID'si
insurerIdentityNumberstring?🔒 Sigorta ettiren TC/VKN
insuredIdentityNumberstring?🔒 Sigortalı TC/VKN
insuredCustomerEmailstring?🔒 Sigortalı email
insurerCustomerEmailstring?🔒 Sigorta ettiren email
fromPolicyTransferboolPoliçe transferi mi?
netPremiumdecimal?Net prim tutarı
grossPremiumdecimal?Brüt prim tutarı
channelChannelSatış kanalı (enum)
insuranceCompanyPolicyNostringSigorta şirketi poliçe numarası

Örnek Payload

{
"$event": "policy.created",
"policyId": "67c94017db57fa44cf64db94",
"proposalId": "67c93f2fdb57fa44cf64db6a",
"productId": 1595,
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD",
"insuranceCompany": {
"id": 12,
"name": "Anadolu Sigorta",
"logo": "https://cdn.insurup.com/logos/anadolu.png",
"enabled": true,
"supportedPaymentOptions": ["SYNC_CREDIT_CARD", "SYNC_OPEN_ACCOUNT"]
},
"startDate": "2025-03-06",
"endDate": "2026-03-06",
"renewalNumber": 0,
"productBranch": "DASK",
"insurerCustomerId": "256e55a5-e1c5-483e-97df-4156d352fb63",
"insuredCustomerId": "256e55a5-e1c5-483e-97df-4156d352fb63",
"insurerIdentityNumber": "12345678910",
"insuredIdentityNumber": "12345678910",
"insuredCustomerEmail": "customer@insurup.com",
"insurerCustomerEmail": "customer@insurup.com",
"fromPolicyTransfer": false,
"netPremium": 1500.00,
"grossPremium": 1650.00,
"channel": "WEBSITE",
"insuranceCompanyPolicyNo": "POL-2025-123456"
}

policy.updated async

Mevcut bir sigorta poliçesi güncellendiğinde veya değiştirildiğinde tetiklenir. Zeyilname işlemleri ve iptal durumlarında çalışır.

Alan Referansı

AlanTipZorunluAçıklama
$eventstringEvent tanımlayıcısı (policy.updated)
policyIdstringPoliçe ID'si
installmentNumberint?Taksit sayısı
paymentTypePaymentOptionÖdeme tipi (enum)
endorsementNumberbyteZeyilname numarası
isCancelboolİptal işlemi mi?
netPremiumdecimalNet prim tutarı
grossPremiumdecimalBrüt prim tutarı
insurerIdentityNumberstring?🔒 Sigorta ettiren TC/VKN
insuredIdentityNumberstring?🔒 Sigortalı TC/VKN
insuranceCompanyPolicyNostringSigorta şirketi poliçe numarası

Örnek Payload

{
"$event": "policy.updated",
"policyId": "67c930b9db57fa44cf64daf6",
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD",
"endorsementNumber": 1,
"isCancel": false,
"netPremium": 250.00,
"grossPremium": 275.00,
"insurerIdentityNumber": "12345678910",
"insuredIdentityNumber": "12345678910",
"insuranceCompanyPolicyNo": "POL-2025-123456"
}

Örnek İptal Payload'ı

{
"$event": "policy.updated",
"policyId": "67c930b9db57fa44cf64daf6",
"installmentNumber": 1,
"paymentType": "SYNC_CREDIT_CARD",
"endorsementNumber": 2,
"isCancel": true,
"netPremium": -1500.00,
"grossPremium": -1650.00,
"insurerIdentityNumber": "12345678910",
"insuredIdentityNumber": "12345678910",
"insuranceCompanyPolicyNo": "POL-2025-123456"
}

Model Referansları

PremiumModel

Prim detaylarını içeren model.

AlanTipZorunluAçıklama
installmentNumberintTaksit numarası
netPremiumdecimalNet prim tutarı
grossPremiumdecimalBrüt prim tutarı
commissiondecimalKomisyon tutarı
exchangeRatedecimalDöviz kuru
currencyCurrencyPara birimi (enum)
insuranceCompanyProposalNumberstring?Sigorta şirketi teklif numarası

CustomerModel (Polimorfik)

Müşteri bilgilerini içeren polimorfik model. $type alanına göre 3 farklı tip olabilir.

IndividualCustomerModel ($type: "individual")

Bireysel müşteri modeli.

AlanTipZorunluAçıklama
$typestring"individual" sabit değer
identityNumberstring🔒 TC Kimlik numarası
birthDateDateOnlyDoğum tarihi (YYYY-MM-DD)
fullNamestring🔒 Ad soyad
phoneNumberCustomerPhoneNumber?🔒 Telefon numarası
emailCustomerEmail?🔒 E-posta adresi
cityInsuranceParameter?İl bilgisi
districtInsuranceParameter?İlçe bilgisi

ForeignCustomerModel ($type: "foreign")

Yabancı uyruklu müşteri modeli.

AlanTipZorunluAçıklama
$typestring"foreign" sabit değer
identityNumberstring🔒 Yabancı kimlik numarası
birthDateDateOnlyDoğum tarihi (YYYY-MM-DD)
fullNamestring🔒 Ad soyad
phoneNumberCustomerPhoneNumber?🔒 Telefon numarası
emailCustomerEmail?🔒 E-posta adresi
cityInsuranceParameter?İl bilgisi
districtInsuranceParameter?İlçe bilgisi

CompanyCustomerModel ($type: "company")

Tüzel müşteri (şirket) modeli.

AlanTipZorunluAçıklama
$typestring"company" sabit değer
titlestring🔒 Şirket unvanı
taxNumberstring🔒 Vergi numarası
phoneNumberCustomerPhoneNumber?🔒 Telefon numarası
emailCustomerEmail?🔒 E-posta adresi
cityInsuranceParameter?İl bilgisi
districtInsuranceParameter?İlçe bilgisi

CustomerPhoneNumber

Telefon numarası detaylarını içeren model.

AlanTipZorunluAçıklama
numberstringTam telefon numarası
countryCodeintÜlke kodu (örn: 90)
areaCodestringAlan kodu (örn: 543)
numberWithoutAreaCodestringAlan kodu hariç numara

CustomerEmail

E-posta adresini içeren model.

AlanTipZorunluAçıklama
valuestringE-posta adresi

InsuranceParameter

Sigorta parametresi modeli (il, ilçe vb. için kullanılır).

AlanTipZorunluAçıklama
valuestringParametre değeri/kodu
textstringParametre açıklaması

InsuranceCompanyModel

Sigorta şirketi bilgilerini içeren model.

AlanTipZorunluAçıklama
idintSigorta şirketi ID'si
namestringSigorta şirketi adı
logostring?Logo URL'i
enabledboolAktif mi?
supportedPaymentOptionsPaymentOption[]Desteklenen ödeme seçenekleri

Enum Değerleri

PaymentOption

Ödeme seçenekleri.

DeğerJSON DeğeriAçıklama
UnknownUNKNOWNBilinmeyen
SyncCreditCardSYNC_CREDIT_CARDSenkron kredi kartı ödemesi
SyncOpenAccountSYNC_OPEN_ACCOUNTSenkron açık hesap ödemesi
Async3DSecureASYNC_3D_SECUREAsenkron 3D Secure ödemesi
AsyncInsuranceCompanyRedirectASYNC_INSURANCE_COMPANY_REDIRECTSigorta şirketi yönlendirmeli ödeme
AsyncThirdParty3DSecureASYNC_THIRD_PARTY_3D_SECUREÜçüncü parti 3D Secure ödemesi

Currency

Para birimi.

DeğerJSON DeğeriAçıklama
UnknownUNKNOWNBilinmeyen
TurkishLiraTURKISH_LIRATürk Lirası (TRY)
UnitedStatesDollarUNITED_STATES_DOLLARAmerikan Doları (USD)
EuroEUROEuro (EUR)

ProductBranch

Ürün dalları.

DeğerJSON DeğeriAçıklama
KaskoKASKOKasko sigortası
TrafikTRAFIKZorunlu trafik sigortası
DaskDASKDASK (Zorunlu deprem sigortası)
KonutKONUTKonut sigortası
TssTSSTamamlayıcı sağlık sigortası
ImmIMMİhtiyari mali mesuliyet
YesilKartYESIL_KARTYeşil kart sigortası
SaglikSAGLIKSağlık sigortası
SeyahatSEYAHATSeyahat sigortası
FerdiFERDIFerdi kaza sigortası
IsyeriISYERIİşyeri sigortası

Channel

Satış kanalları.

DeğerJSON DeğeriAçıklama
UnknownUNKNOWNBilinmeyen
ManualMANUALManuel giriş
WebsiteWEBSITEWeb sitesi
GoogleAdsGOOGLE_ADSGoogle Ads
CallCenterCALL_CENTERÇağrı merkezi
MobileAppMOBILE_APPMobil uygulama
ApiAPIAPI entegrasyonu
PartnerPARTNERİş ortağı

🔒 Veri Güvenliği

Maskelenmiş Alanlar

Tablolarda 🔒 simgesiyle işaretlenmiş alanlar (TC kimlik, email, telefon, vergi numarası vb.) hassas kişisel veri içerir. Bu alanlar:

  • Loglarda maskelenerek gösterilir
  • KVKK ve GDPR uyumluluğu kapsamında korunur
  • Güvenli bir şekilde iletilir ancak loglama sistemlerinde tam değerleri gösterilmez

Signature Validasyonu

Webhook'larınızın güvenliğini sağlamak için, gelen isteklerin gerçekten InsurUp tarafından gönderildiğini doğrulamak amacıyla imza doğrulaması yapmanız önemlidir.

İmza, x-webhook-signature header'ında gönderilir ve payload'ın secret ile SHA-256 algoritması kullanılarak şifrelenmesiyle oluşturulur.

Python

import hmac
import hashlib

def validate_signature(secret, payload, signature):
computed_signature = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(computed_signature, signature)

JavaScript

const crypto = require('crypto');

function validateSignature(secret, payload, signature) {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(computedSignature, 'hex'), Buffer.from(signature, 'hex'));
}

C#

bool ValidateSignature(string secret, string payload, string signature)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));

var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var computedSignature = BitConverter.ToString(computedHash).Replace("-", "").ToLower();

return computedSignature == signature.ToLower();
}

PHP

function validate_signature($secret, $payload, $signature) {
$computed_signature = hash_hmac('sha256', $payload, $secret);
return hash_equals($computed_signature, $signature);
}

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class SignatureValidator {
public static boolean validateSignature(String secret, String payload, String signature) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);

byte[] hash = sha256_HMAC.doFinal(payload.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString().equals(signature.toLowerCase());
}
}

Hata Yönetimi ve Yeniden Deneme

Webhook endpoint'iniz başarılı bir yanıt (HTTP 2xx) döndürmezse, InsurUp sistemi otomatik olarak yeniden deneme yapar:

  • Maksimum deneme sayısı: 3
  • Deneme aralığı: Üstel geri çekilme (exponential backoff)
  • Timeout: Her istek için 30 saniye
En İyi Uygulamalar
  1. Webhook endpoint'iniz her zaman hızlı yanıt vermelidir (< 5 saniye)
  2. Uzun süren işlemleri asenkron olarak kuyruğa alın
  3. İdempotent işlem yapın - aynı webhook birden fazla kez gelebilir
  4. x-webhook-delivery header'ını kullanarak tekrarlayan istekleri tespit edin