Linkleri Yönetme
Oluşturduğunuz linkleri bu sayfadaki uçlarla yönetirsiniz. Bütün uçlar Link Oluşturma sayfasında anlatılan imzalı istek ile çağrılır ve anahtarınızın ilgili payment-link:* yetkisini ister. Bir anahtar yalnız kendi ortamındaki (TEST ya da LIVE) linkleri görür; başka bir organizasyonun ya da diğer ortamın linki 404 döner. Aynı işlemleri panelden de yapabilirsiniz.
Tüm tutarlar minor-unit (kuruş) cinsinden tam sayıdır: "collectedAmountMinor": 150000 = ₺1.500,00.
| Yöntem | Yol | Yetki | Idempotency-Key |
|---|---|---|---|
GET | /api/v1/payments/links | payment-link:view | — |
GET | /api/v1/payments/links/:id | payment-link:view | — |
PATCH | /api/v1/payments/links/:id | payment-link:manage | İsteğe bağlı |
POST | /api/v1/payments/links/:id/pause · /resume · /deactivate | payment-link:manage | İsteğe bağlı |
POST | /api/v1/payments/links/:id/send | payment-link:send | Zorunlu |
GET | /api/v1/payments/links/:id/qr | payment-link:view | — |
GET | /api/v1/payments/links/:id/attempts | payment-link:view | — |
GET | /api/v1/payments/links/:id/payments | payment-link:view | — |
Node.js örnekleri Link Oluşturma sayfasındaki signedHeaders yardımcısını kullanır. cURL örnekleri aynı imzalama adımlarının kabuk fonksiyonu hâlini kullanır:
# lunixi-sign.sh — OpenSSL 3.0+ gerekir.
# Kullanım: source lunixi-sign.sh
# lunixi_sign GET "/api/v1/payments/links?limit=25"
# lunixi_sign POST "/api/v1/payments/links/<id>/pause" "$BODY"
LUNIXI_KEY_ID="mk_test_sk_..."
LUNIXI_KEY_FILE="lunixi-signing.key"
lunixi_sign() {
local method="$1" req_path="$2" body="${3-}"
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
NONCE=$(openssl rand -hex 16)
if [ -n "$body" ]; then
DIGEST="SHA-256=$(printf '%s' "$body" | openssl dgst -sha256 -binary | base64)"
printf '%s\n%s\nX-Date:%s\nX-Nonce:%s\nDigest:%s' "$method" "$req_path" "$DATE" "$NONCE" "$DIGEST" > canonical.txt
else
DIGEST=""
printf '%s\n%s\nX-Date:%s\nX-Nonce:%s' "$method" "$req_path" "$DATE" "$NONCE" > canonical.txt
fi
SIGNATURE=$(openssl pkeyutl -sign -inkey "$LUNIXI_KEY_FILE" -rawin -in canonical.txt | base64 | tr -d '\n')
}Listeleme
GET /api/v1/payments/links linklerinizi en yeniden eskiye, cursor tabanlı sayfalar hâlinde döner.
| Sorgu parametresi | Tip | Açıklama |
|---|---|---|
limit | integer | Sayfa başına kayıt, 1–100. Varsayılan 25. |
cursor | string | Önceki yanıttaki pageInfo.nextCursor. İlk sayfada gönderilmez. |
includeTotal | boolean | true ise pageInfo.totalCount doldurulur. Daha yavaştır; gerekmedikçe göndermeyin. |
state | string | Virgülle ayrılmış durumlar, ör. ACTIVE,PAUSED. |
usage | string | Virgülle ayrılmış: SINGLE_USE,MULTI_USE. |
amountMode | string | Virgülle ayrılmış: FIXED,OPEN,ITEMIZED. |
tag | string | Bu etiketi taşıyan linkler. |
branchCode | string | Bu şube koduna sahip linkler. |
createdById | string | Bu kimliğin oluşturduğu linkler (API ile oluşturulanlarda anahtar kimliği). |
query | string | Kısa kodla tam eşleşme ya da başlık / reference başıyla arama. Kod büyük-küçük harf, tire ve boşluk fark etmeden eşleşir. |
createdFrom, createdTo | string (ISO 8601) | Oluşturulma aralığı; createdFrom dahil, createdTo hariç. |
environment | string | Sonuç her zaman anahtarınızın ortamıyla sınırlıdır. |
source lunixi-sign.sh
REQ_PATH="/api/v1/payments/links?limit=25&state=ACTIVE,PAUSED"
lunixi_sign GET "$REQ_PATH"
curl "https://api-gateway.lunixi.com$REQ_PATH" \
-H "X-Key-Id: $LUNIXI_KEY_ID" \
-H "X-Date: $DATE" \
-H "X-Nonce: $NONCE" \
-H "X-Signature: $SIGNATURE"Yanıt
pageInfo, data'nın yanındadır; liste data.items içindedir.
{
"status": "success",
"code": "SUCCESS",
"data": {
"items": [
{
"id": "5f0c1d2e-8a4b-4c6d-9e7f-1a2b3c4d5e6f",
"shortCode": "7KQ2M9XAPT",
"url": "https://pay.lunixi.com/7KQ2M9XAPT",
"organizationId": "b1d2c3e4-…",
"environment": "TEST",
"state": "ACTIVE",
"usage": "SINGLE_USE",
"amountMode": "FIXED",
"currency": "TRY",
"amountMinor": 150000,
"title": "Kasım danışmanlık bedeli",
"reference": "INV-2026-0042",
"tags": [],
"paidCount": 0,
"collectedAmountMinor": 0,
"expiresAt": "2026-10-31T20:59:59.000Z",
"createdByType": "API_KEY",
"createdById": "mk_test_sk_…",
"createdAt": "2026-09-25T09:00:00.000Z",
"version": 1,
"rowVersion": 1
}
]
},
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null },
"statusCode": 200,
"requestId": "req_7f3d9c1a4b2e"
}Liste satırı özettir; amountMinor yalnız FIXED linklerde doludur. Tam kayıt için GET /api/v1/payments/links/:id çağırın.
Tek link
GET /api/v1/payments/links/:id linkin tam kaydını döner: bütün alanlar, recipient ve prefill dahil, sayaçlar (counters), stok durumu (availability) ve kilit bayrakları. Yanıt şekli oluşturma yanıtıyla aynıdır — bkz. Link Oluşturma › Yanıt.
Güncelleme
PATCH /api/v1/payments/links/:id linkin tanımını değiştirir ve yeni bir sürüm (version) üretir. Süren ödemeler başladıkları sürümün tutar ve kurallarıyla tamamlanır.
| Kural | Ayrıntı |
|---|---|
expectedRowVersion zorunlu | Son okuduğunuz rowVersion. Link arada değiştiyse 409 payment_link.link.version_conflict döner: linki yeniden okuyun, değişikliğinizi yeniden uygulayın. |
| Yalnız gönderdiğiniz alanlar değişir | Gövdedeki her anahtar değişecek bir alandır; göndermediğiniz alanlar olduğu gibi kalır. |
null temizler | ör. "expiresAt": null linki süresiz yapar, "successRedirectUrl": null başarı sonrası yönlendirmeyi kaldırır. |
| Nesne ve diziler bütün olarak değişir | items, buyerFields, customFields, recipient, prefill, verification, reminders, checkout, tags, metadata kısmi birleştirilmez; alanın yeni hâlinin tamamını gönderin. Mevcut bir kalemin itemKey'i değiştirilemez. |
| Değişmez alanlar | usage, amountMode, currency → 422 payment_link.link.immutable_field |
| Tutar kilidi | Süren bir ödeme varken ya da link ödeme almışsa (amountLocked: true) tutar alanları değiştirilemez: amountMinor, minAmountMinor, maxAmountMinor, suggestedAmountsMinor, quantityEnabled, minQuantity, maxQuantity, items, capacity → 409 payment_link.link.amount_locked. İstisna: capacity ve kalemlerin capacity değeri artırılabilir (satılan ve süren ödemelerin tuttuğu birimden az olamaz). Kalem kapasitesini artırmak için items dizisini yalnız capacity değerleri değişmiş olarak gönderin. |
| Kaldırılmış link | TAKEN_DOWN linkte 409 payment_link.link.taken_down |
Başlık, açıklama, bitiş zamanı, alıcı alanları ve atıf alanları gibi tutar dışı alanlar tutar kilidine tabi değildir. Başarılı güncelleme payment.link.updated yayınlar.
source lunixi-sign.sh
LINK_ID="5f0c1d2e-8a4b-4c6d-9e7f-1a2b3c4d5e6f"
REQ_PATH="/api/v1/payments/links/$LINK_ID"
BODY='{"expectedRowVersion":1,"title":"Kasım danışmanlık bedeli (revize)","expiresAt":"2026-11-15T20:59:59.000Z"}'
lunixi_sign PATCH "$REQ_PATH" "$BODY"
curl -X PATCH "https://api-gateway.lunixi.com$REQ_PATH" \
-H "Content-Type: application/json" \
-H "X-Key-Id: $LUNIXI_KEY_ID" \
-H "X-Date: $DATE" \
-H "X-Nonce: $NONCE" \
-H "Digest: $DIGEST" \
-H "X-Signature: $SIGNATURE" \
--data-raw "$BODY"Duraklatma, devam ettirme ve iptal
POST /api/v1/payments/links/:id/pause, /resume ve /deactivate linkin durumunu değiştirir ve güncel linki döner.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
expectedRowVersion | integer | Hayır | Gönderirseniz linkin rowVersion'ıyla eşleşmelidir (409 payment_link.link.version_conflict). Göndermezseniz ya da 0 gönderirseniz kontrol yapılmaz. |
reason | string | Hayır | En fazla 500 karakter; linkin işlem geçmişine yazılır, alıcıya gösterilmez. |
| İşlem | Geçiş | Event |
|---|---|---|
pause | ACTIVE → PAUSED | payment.link.paused |
resume | PAUSED → ACTIVE — expiresAt gelecekte olmalı | payment.link.resumed |
deactivate | ACTIVE ya da PAUSED → DEACTIVATED — kalıcıdır | payment.link.deactivated |
Geçersiz geçiş (ör. COMPLETED bir linki duraklatmak) 409 payment_link.link.invalid_transition döner.
Duraklatma ve iptal, o anda süren bir ödemeyi durdurmaz. Alıcı ödeme formundaysa ödeme tamamlanabilir; o durumda payment.captured yine gelir ve linkin sayaçları güncellenir. Siparişi her zaman payment.captured ile değerlendirin.
source lunixi-sign.sh
REQ_PATH="/api/v1/payments/links/$LINK_ID/pause"
BODY='{"expectedRowVersion":2,"reason":"Stok sayımı"}'
lunixi_sign POST "$REQ_PATH" "$BODY"
curl -X POST "https://api-gateway.lunixi.com$REQ_PATH" \
-H "Content-Type: application/json" \
-H "X-Key-Id: $LUNIXI_KEY_ID" -H "X-Date: $DATE" -H "X-Nonce: $NONCE" \
-H "Digest: $DIGEST" -H "X-Signature: $SIGNATURE" \
--data-raw "$BODY"Gönderme
POST /api/v1/payments/links/:id/send linki Lunixi üzerinden e-posta ya da SMS ile gönderir. Idempotency-Key zorunludur: aynı anahtarla tekrar isteği yeni bir gönderim yapmaz, ilk gönderimi replayed: true ile döner; aynı anahtar farklı gövdeyle 409 payment_link.idempotency.conflict alır.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
channel | string | Evet | EMAIL | SMS |
recipientEmail | string | Hayır | Boşsa linkin recipient.email adresi kullanılır. |
recipientPhone | string | Hayır | E.164. Boşsa linkin recipient.phone numarası kullanılır. |
locale | string | Hayır | İleti dili: tr | en. |
{
"status": "success",
"code": "SUCCESS",
"data": {
"delivery": {
"id": "0e8a7c55-…",
"kind": "REQUEST",
"channel": "EMAIL",
"recipientMasked": "a***@example.com",
"state": "QUEUED",
"failureReason": null,
"attemptId": null,
"createdAt": "2026-09-25T09:05:00.000Z",
"updatedAt": "2026-09-25T09:05:00.000Z"
},
"replayed": false
},
"statusCode": 200,
"requestId": "req_…"
}Gönderim QUEUED olarak kaydedilir ya da hemen FAILED döner. Sonraki durum değişiklikleri (SENT, DELIVERED, FAILED) panelde linkin gönderim geçmişinde görünür.
failureReason | Anlamı | Ne yapmalı |
|---|---|---|
channel_not_available | Seçilen kanal hesabınız için henüz kullanılabilir değil | Linki kendi kanalınızdan ya da QR ile paylaşın |
test_mode_recipient_not_allowed | TEST ortamında alıcı, organizasyonunuzun doğrulanmış bir üyesi değil (TEST'te SMS gönderilmez) | Test gönderimlerini kendi ekibinizin adresine yapın |
invalid_recipient | Adres ya da numara geçersiz | Alıcı bilgisini düzeltip yeni bir Idempotency-Key ile gönderin |
provider_rejected | Gönderim sağlayıcısı iletiyi reddetti | Alıcı bilgisini kontrol edin |
suppressed | Alıcı adresi gönderim engel listesinde | Başka bir kanal ya da adres kullanın |
mock_delivery | Gönderim simüle edildi, ileti alıcıya ulaşmadı | Linki kendi kanalınızdan paylaşın |
render_failed, dispatch_failed | İleti hazırlanamadı ya da iletilemedi | Yeni bir Idempotency-Key ile tekrar deneyin |
- Kaldırılmış linkte gönderim
409 payment_link.link.taken_downdöner. - Gönderim, linkin erişim doğrulaması kilidini de açar (
verificationLocked: false): alıcı çok fazla hatalı kod girdiyse yeni kod isteyebilmesi için linki yeniden gönderin. - Hatırlatmalar (
reminders) ayrı bir çağrı gerektirmez;recipientdolu tek kullanımlık linkte tanımladığınız aralıkla gönderilir.
QR kodu
GET /api/v1/payments/links/:id/qr linkin adresini (https://pay.lunixi.com/<KOD>) içeren QR kodunu görsel olarak döner — JSON değil.
| Sorgu parametresi | Değer |
|---|---|
format | svg (varsayılan) | png |
size | Piksel, 128–2048. Varsayılan 512. |
Yanıt Content-Type: image/svg+xml ya da image/png ve Cache-Control: no-store taşır. Hata durumunda standart JSON hata zarfı döner. Kaldırılmış linkte 409 payment_link.link.taken_down.
Bu bir URL QR'ıdır; TR Karekod değildir. Alıcı telefon kamerasıyla okutup ödeme sayfasını açar.
source lunixi-sign.sh
REQ_PATH="/api/v1/payments/links/$LINK_ID/qr?format=png&size=1024"
lunixi_sign GET "$REQ_PATH"
curl "https://api-gateway.lunixi.com$REQ_PATH" \
-H "X-Key-Id: $LUNIXI_KEY_ID" -H "X-Date: $DATE" -H "X-Nonce: $NONCE" \
-H "X-Signature: $SIGNATURE" \
-o link-qr.pngÖdeme denemeleri
GET /api/v1/payments/links/:id/attempts linkte başlatılan her ödeme denemesini en yeniden eskiye döner. Parametreler: limit, cursor ve virgülle ayrılmış state.
Deneme state | Anlamı |
|---|---|
OPEN | Deneme açıldı, ödeme formu hazırlanıyor |
BOUND | Ödeme formu açıldı; alıcı ödüyor ya da bankanın sonucu bekleniyor |
SUCCEEDED | Ödeme tahsil edildi |
FAILED | Ödeme kesin olarak başarısız oldu |
EXPIRED | Alıcı ödemeyi süresi içinde tamamlamadı |
ABANDONED | Ödeme formu hiç açılmadı |
NEEDS_REVIEW | Sonuç otomatik uygulanamadı; Lunixi operasyon ekibi inceler |
Bir deneme sürerken ayırdığı stok (tek kullanımlık linkte linkin kendisi) yalnız ödemenin kesin sonucuyla serbest bırakılır. Bankadan sonucu henüz gelmemiş bir ödeme için stok, süre dolsa bile tutulmaya devam eder; bu yüzden reservedQuantity bir süre dolu görünebilir.
| Alan | Açıklama |
|---|---|
id | Deneme kimliği — ödeme webhook'larında paymentLinkAttemptId |
state | Yukarıdaki tablo |
linkVersion | Denemenin bağlı olduğu link sürümü |
paymentId | Ödeme kimliği (webhook'larda intentId); form açılmadıysa null |
amountMinor, currency, quantity | Tahsil edilecek tutar ve adet |
lines[] | Kalemli linkte { itemKey, name, quantity, unitPriceMinor, lineTotalMinor } |
buyerName, buyerEmail, buyerPhone | Alıcının girdiği bilgiler |
customFields[] | { key, value } — özel alan cevapları |
failureCode | Başarısız denemede kanonik ret anahtarı, ör. card.insufficient_funds |
outcomeCertainty | DEFINITIVE_FAILURE | UNKNOWN | null |
reservationState | HELD (tutuluyor) | CONVERTED (satışa döndü) | RELEASED (bırakıldı) |
createdAt, boundAt, finalizedAt | Zaman damgaları |
Deneme kayıtları alıcının kişisel verilerini içerir; kendi sistemlerinizde buna göre saklayın.
Tahsilatlar
GET /api/v1/payments/links/:id/payments linkin başarılı ödemelerini iade toplamlarıyla birlikte döner. Parametreler: limit, cursor.
| Alan | Açıklama |
|---|---|
attemptId, paymentId | Deneme ve ödeme kimlikleri |
paymentStatus | CAPTURED | PARTIALLY_REFUNDED | REFUNDED |
amountMinor | Ödemenin tutarı (taksit vade farkı hariç) |
capturedAmountMinor, refundedAmountMinor | Tahsil edilen ve iade edilen tutar |
currency, paidAt | Para birimi ve ödeme zamanı |
buyerEmail | Alıcının e-postası |
receiptNumber | Makbuz numarası, ör. PL-20260925-7KQ2M9XAPT |
İade için mevcut İade ucunu paymentId ile kullanın. İade linkin durumunu değiştirmez: tek kullanımlık link COMPLETED kalır, çok kullanımlık linkte satılan stok geri eklenmez.
Hatalar
| Status | Kod | Ne yapmalı |
|---|---|---|
400 | INVALID_CURSOR | Önceki yanıttaki pageInfo.nextCursor değerini aynen gönderin; filtreyi değiştirdiyseniz baştan başlayın |
400 | payment_link.idempotency.key_required | send için Idempotency-Key gönderin |
403 | API_INSUFFICIENT_SCOPE | Anahtarınıza ilgili payment-link:* yetkisini ekleyin |
404 | payment_link.link.not_found | Link yok, başka bir organizasyonun ya da diğer ortamın linki |
409 | payment_link.link.version_conflict | Linki yeniden okuyup güncel rowVersion ile tekrar deneyin |
409 | payment_link.link.invalid_transition | Linkin güncel state'ine bakın; sonlanmış link yeniden açılmaz |
409 | payment_link.link.amount_locked | Tutarı değiştirmek için yeni link oluşturun |
409 | payment_link.link.taken_down | Link Lunixi tarafından kaldırıldı; değişiklik ve gönderim yapılamaz |
409 | payment_link.idempotency.conflict | Farklı bir gönderim için yeni Idempotency-Key üretin |
422 | payment_link.link.immutable_field | usage, amountMode, currency değişmez; yeni link oluşturun |
422 | payment_link.validation.invalid | details.errors listesindeki alanları düzeltin |
İmza hataları (401) için: Link Oluşturma › Hatalar. 5xx yanıtlarında isteği üstel geri çekilmeyle yeniden deneyin; send çağrısını aynı Idempotency-Key ile tekrarlarsanız ikinci bir gönderim yapılmaz.
Sonraki adımlar
- Ödeme Sayfası — alıcının gördüğü sayfa ve erişim doğrulaması
- Webhook'lar — link event'leri ve siparişi teslim etme
- Sayfalama —
limit+cursorstandardı