Linkle Ödeme Webhook'ları
Ödeme linkleri iki tür webhook üretir:
- Ödeme event'leri — linkle alınan bir ödeme, diğer ödemeleriniz gibi
payment.captured,payment.failed,payment.refunded… event'lerini üretir. Bu event'lere linki tanımlayan alanlar eklenir. - Link yaşam döngüsü event'leri —
payment.link.*: linkin oluşturulması, güncellenmesi, duraklatılması, süresinin dolması, tamamlanması.
Siparişi payment.captured ile teslim edin. Linkle alınan ödemede de para sinyali tektir: payment.captured. payment.link.completed yalnız tek kullanımlık linkin kapandığını bildirir; ikinci bir "ödendi" sinyali değildir. Sonuç sayfası ve successRedirectUrl yönlendirmesi de ödeme kanıtı değildir.
Endpoint yapılandırması, imza doğrulama ve teslimat sözleşmesi bütün ürünlerde ortaktır — bkz. Webhook Kurulumu, Webhook'lar ve Ödeme Webhook'ları.
Abonelik
Link event'leri PAYMENT_GATEWAY ürününe aittir. Webhook endpoint'inizin eventTypes listesine şunlardan birini ekleyin:
eventTypes | Neyi kapsar |
|---|---|
payment.link.* | Dokuz link yaşam döngüsü event'inin tamamı |
payment.link.completed, payment.link.expired … | Yalnız seçtiğiniz event'ler |
payment.* | Bütün ödeme event'leri ve link event'leri |
Ödeme event'leri (payment.captured vb.) için ayrı bir abonelik gerekmez; mevcut aboneliğiniz linkle alınan ödemeleri de kapsar.
Abone olabileceğiniz event'leri planınız belirler; panelin webhook ekranı her event'in planınıza dahil olup olmadığını gösterir. Planınızın kapsamadığı bir event tipiyle endpoint oluşturma ya da güncelleme isteği 403 ile reddedilir. Joker abonelikler de plan listesiyle karşılaştırılır: payment.link.* ya da payment.* yalnız planınız o jokeri kapsıyorsa kabul edilir; kapsamıyorsa link event'lerini adlarıyla ekleyin. Plan değişikliğinden sonra kapsam dışında kalan event'ler teslim edilmez.
Ödeme event'lerindeki link alanları
Linkle alınan bir ödemenin her payment.* event'inde data şu alanları da taşır. Link dışındaki ödemelerde bu alanlar hiç bulunmaz (null değil, yok).
| Alan | Değer |
|---|---|
source | "PAYMENT_LINK" |
paymentLinkId | Linkin id'si |
paymentLinkCode | Linkin 10 karakterlik kodu |
paymentLinkAttemptId | Ödeme denemesinin kimliği — ödeme denemelerindeki id |
Link ödemelerinde orderId Lunixi tarafından üretilir: tek kullanımlık linkte PL-<KOD>, çok kullanımlık linkte PL-<KOD>-<paymentLinkAttemptId>. intentId, link uçlarındaki paymentId ile aynıdır.
{
"id": "2d8f4a1c-6b3e-5f70-9a2b-4c6d8e0f1a3b",
"type": "payment.captured",
"sourceService": "payment-service",
"organizationId": "b1d2c3e4-…",
"productCode": "PAYMENT_GATEWAY",
"environment": "LIVE",
"eventVersion": 1,
"schemaVersion": "v1",
"createdAt": "2026-09-25T10:14:02.000Z",
"data": {
"intentId": "9c6f2b1a-4e8d-4a3f-b5e6-2d7c1a9b8e30",
"merchantId": "b1d2c3e4-…",
"orderId": "PL-7KQ2M9XAPT",
"currency": "TRY",
"status": "CAPTURED",
"capturedAmountMinor": "150000",
"source": "PAYMENT_LINK",
"paymentLinkId": "5f0c1d2e-8a4b-4c6d-9e7f-1a2b3c4d5e6f",
"paymentLinkCode": "7KQ2M9XAPT",
"paymentLinkAttemptId": "0b6f3e2a-1c4d-4e5f-8a9b-7c6d5e4f3a2b"
}
}Siparişi teslim etme
İmzayı doğrulayın ve hızlı onaylayın
x-lunixi-signature'ı doğrulayın, event'i kendi kuyruğunuza yazın ve 2xx dönün.
Event'i linkinizle eşleştirin
data.source === "PAYMENT_LINK" ise paymentLinkId ile, linki oluştururken kendi sisteminizde sakladığınız kayda (sipariş, fatura, müşteri) gidin. Link oluştururken verdiğiniz reference ve metadata ödeme event'inde yer almaz; gerekirse GET /api/v1/payments/links/:id ile okuyun ya da payment.link.* event'lerinden alın.
Bir kez işleyin
Teslimat en az bir kez yapılır ve sırası garanti edilmez. Event'in id'sini tekilleştirme anahtarı olarak kullanın; aynı ödeme denemesi (paymentLinkAttemptId) için siparişi yalnız bir kez teslim edin.
Teslim edin
payment.captured geldiğinde tahsilat gerçekleşmiştir. Çok kullanımlık linkte her başarılı ödeme ayrı bir payment.captured üretir; link açık kalır.
Link yaşam döngüsü event'leri
| Event | Ne zaman tetiklenir |
|---|---|
payment.link.created | Link oluşturuldu |
payment.link.updated | Link güncellendi; yeni version |
payment.link.paused | Link duraklatıldı |
payment.link.resumed | Link yeniden açıldı |
payment.link.deactivated | Link iptal edildi |
payment.link.expired | expiresAt geçti |
payment.link.completed | Tek kullanımlık link ödendi; paymentId ve attemptId taşır |
payment.link.taken_down | Lunixi linki yayından kaldırdı; takedownReasonCode taşır |
payment.link.takedown_reverted | Lunixi kaldırmayı geri aldı; link önceki durumuna döndü |
Çok kullanımlık linkte her ödeme için ayrı bir link event'i üretilmez; ödemeleri payment.captured ile izlersiniz.
Payload
{
"id": "7a1e9c3b-5d2f-5a84-b6c1-3e9f0a2d4b6c",
"type": "payment.link.completed",
"sourceService": "payment-link-service",
"organizationId": "b1d2c3e4-…",
"productCode": "PAYMENT_GATEWAY",
"environment": "LIVE",
"eventVersion": 1,
"schemaVersion": "v1",
"createdAt": "2026-09-25T10:14:03.000Z",
"data": {
"paymentLinkId": "5f0c1d2e-8a4b-4c6d-9e7f-1a2b3c4d5e6f",
"shortCode": "7KQ2M9XAPT",
"url": "https://pay.lunixi.com/7KQ2M9XAPT",
"state": "COMPLETED",
"previousState": "ACTIVE",
"version": 1,
"usage": "SINGLE_USE",
"amountMode": "FIXED",
"currency": "TRY",
"amountMinor": "150000",
"title": "Kasım danışmanlık bedeli",
"reference": "INV-2026-0042",
"metadata": { "crmId": "A-77" },
"paidCount": 1,
"collectedAmountMinor": "150000",
"soldQuantity": 1,
"expiresAt": "2026-10-31T20:59:59.000Z",
"paymentId": "9c6f2b1a-4e8d-4a3f-b5e6-2d7c1a9b8e30",
"attemptId": "0b6f3e2a-1c4d-4e5f-8a9b-7c6d5e4f3a2b"
}
}data alanı | Açıklama |
|---|---|
paymentLinkId, shortCode, url | Linkin kimliği, kodu ve adresi |
state, previousState | Event anındaki durum ve bir önceki durum |
version | Linkin event anındaki sürümü |
usage, amountMode, currency | Link tipi ve para birimi |
amountMinor | Minor-unit string; yalnız FIXED linkte dolu, diğerlerinde null |
title, reference | Başlık ve referansınız (reference yoksa null) |
metadata | Linkte tanımladığınız anahtar-değer çiftleri |
paidCount, soldQuantity | Başarılı ödeme sayısı ve satılan birim |
collectedAmountMinor | Tahsil edilen toplam, minor-unit string |
expiresAt | Bitiş zamanı; yoksa null |
paymentId, attemptId | Yalnız payment.link.completed |
takedownReasonCode | Yalnız payment.link.taken_down: PHISHING, FRAUD, BRAND_IMPERSONATION, PROHIBITED_GOODS, LEGAL_REQUEST, OTHER |
data, event'in anlattığı andaki durumu gösterir. Linkin güncel durumu için GET /api/v1/payments/links/:id çağırın.
Teslimat
Link event'leri ödeme event'leriyle aynı teslimat modelini kullanır:
- İmzalı —
x-lunixi-signaturebaşlığını gövdeye güvenmeden önce doğrulayın. - Retry'lı —
2xxalınamazsa teslimat backoff ile yeniden denenir; her tekrar aynıid'yi taşır. - En az bir kez, sırasız — aynı event birden çok kez gelebilir ve event'ler oluşma sırasıyla gelmeyebilir. Mantığınızı geliş sırasına değil
stateveversiondeğerlerine dayandırın.
İadeler
Linkle alınan bir ödemenin iadesi payment.refunded ya da payment.partially_refunded üretir; bu event'ler de link alanlarını taşır. İade linkin durumunu değiştirmez: tek kullanımlık link COMPLETED kalır, çok kullanımlık linkte satılan stok geri eklenmez.
Sonraki adımlar
- Ödeme Webhook'ları — bütün
payment.*event'leri ve alanları - Webhook Kurulumu — endpoint oluşturma, olay aboneliği ve imza secret'ı
- Webhook'lar — teslimat başlıkları, imza doğrulama ve yeniden deneme politikası
- Linkleri Yönetme — linkin güncel durumunu okuma