Link Oluşturma
POST /api/v1/payments/links yeni bir ödeme linki oluşturur ve paylaşacağınız https://pay.lunixi.com/<KOD> adresini döner. Bu sayfa kimlik doğrulamayı, isteğin bütün alanlarını, yanıtı ve hataları anlatır. Linki panelden de oluşturabilirsiniz; bu sayfa sunucunuzdan yapılan API entegrasyonu içindir.
Tüm tutarlar minor-unit (kuruş) cinsinden tam sayıdır: "amountMinor": 150000 = ₺1.500,00. amountMinor, minAmountMinor, maxAmountMinor, suggestedAmountsMinor ve items[].unitPriceMinor için geçerlidir. Ondalıklı tutar göndermeyin.
Nasıl çalışır
Anahtarınıza yetki verin
API anahtarınızın Yetkiler listesinde payment-link:create (ve kullanacağınız diğer payment-link:* kodları) olmalıdır — aşağıdaki Yetkiler bölümüne bakın.
İsteği imzalayıp gönderin
Gövdeyi hazırlayın, Ed25519 anahtarınızla imzalayın ve bir Idempotency-Key ile POST /api/v1/payments/links çağırın.
Adresi paylaşın
Yanıttaki url alanını alıcınıza iletin ya da QR kodunu indirin. Link oluşturulduğu anda ACTIVE'dir (startsAt verdiyseniz o ana kadar ödeme başlatılamaz).
Ödemeyi webhook ile izleyin
Ödeme tahsil edildiğinde payment.captured gelir; paymentLinkId ile linkinize eşleştirirsiniz. → Webhook'lar
Kimlik doğrulama
Ödeme linki uçları (/api/v1/payments/links/*) yalnız API anahtarınızla imzalanmış istek kabul eder. Her istek aşağıdaki başlıkları taşır; Authorization başlığı gerekmez. Bearer erişim token'ı ya da panel oturumu bu uçlarda kimlik yerine geçmez — imza başlıkları olmayan istek 401 AUTH_HEADERS_MISSING alır.
| Başlık | Değer | Zorunlu |
|---|---|---|
X-Key-Id | Anahtarınızın kimliği (kid) — test için mk_test_sk_…, canlı için mk_live_sk_… | Evet |
X-Date | ISO 8601 zaman damgası — sunucu saatine göre ±5 dakika içinde | Evet |
X-Nonce | İstek başına benzersiz değer (UUID ya da rastgele hex) — tek kullanımlıktır | Evet |
Digest | Gövdenin SHA-256=<base64> hash'i | Gövdeli isteklerde |
X-Signature | Aşağıdaki kanonik dizinin Base64 Ed25519 imzası | Evet |
İmzalanan metin, satırları \n ile birleştirilmiş şu yapıdır (örnekteki Digest, aşağıdaki örnek isteğin gövdesine aittir):
POST
/api/v1/payments/links
X-Date:2026-09-25T09:00:00Z
X-Nonce:64ae70b60739b3515d972c0378854a59
Digest:SHA-256=DshE/z0IEfWv/itO+8GjSJCAVm7v4gZyyw7vIML0Edo=- İkinci satır tam istek yoludur ve varsa sorgu dizesini de içerir:
GET /api/v1/payments/links?limit=25&state=ACTIVEimzalanırken ikinci satır/api/v1/payments/links?limit=25&state=ACTIVEolmalıdır — gönderdiğiniz sırayla ve kodlamayla. - Gövdesiz istekte (
GET)Digestsatırı hiç yazılmaz. - Digest'i gönderdiğiniz gövdenin kendisinden hesaplayın ve gövdeyi boşluksuz JSON olarak gönderin (
JSON.stringifyçıktısı gibi). Sunucu digest'i ayrıştırılmış gövdenin yeniden serileştirilmiş hâli üzerinden doğrular; girintili (pretty-printed) bir gövde401 INVALID_DIGESTalır.
Bu bölümdeki Node.js örnekleri aşağıdaki signedHeaders yardımcısını kullanır. Özel anahtarınız sunucunuzda kalır; tarayıcıya ya da mobil uygulamaya asla konmaz.
import { createHash, createPrivateKey, sign, randomUUID } from 'node:crypto';
export const BASE_URL = 'https://api-gateway.lunixi.com';
const signingKey = createPrivateKey(process.env.LUNIXI_SIGNING_KEY_PEM);
// pathWithQuery: sorgu dizesi dahil tam yol, ör. '/api/v1/payments/links?limit=25'
// body: gönderdiğiniz JSON dizesinin kendisi; gövdesiz istekte verilmez
export function signedHeaders(method, pathWithQuery, body) {
const date = new Date().toISOString();
const nonce = randomUUID();
const headers = { 'X-Key-Id': process.env.LUNIXI_KEY_ID, 'X-Date': date, 'X-Nonce': nonce };
const lines = [method, pathWithQuery, `X-Date:${date}`, `X-Nonce:${nonce}`];
if (body !== undefined) {
const digest = 'SHA-256=' + createHash('sha256').update(body).digest('base64');
headers['Content-Type'] = 'application/json';
headers['Digest'] = digest;
lines.push(`Digest:${digest}`);
}
headers['X-Signature'] = sign(null, Buffer.from(lines.join('\n')), signingKey).toString('base64');
return headers;
}cURL örnekleri imzayı OpenSSL 3.0 veya üstü ile hesaplar (openssl pkeyutl -rawin). Anahtar kaydı ve döndürme: Kimlik Doğrulama.
Yetkiler
İmza doğrulandıktan sonra anahtarın yetkisi (scope) kontrol edilir. Eksik yetki 403 API_INSUFFICIENT_SCOPE döner.
| Yetki | Uçlar |
|---|---|
payment-link:create | POST /payments/links |
payment-link:view | GET /payments/links, GET /payments/links/:id, GET /:id/qr, GET /:id/attempts, GET /:id/payments |
payment-link:manage | PATCH /payments/links/:id, POST /:id/pause, POST /:id/resume, POST /:id/deactivate |
payment-link:send | POST /payments/links/:id/send |
Mevcut anahtarlarınız bu yetkileri kendiliğinden almaz. payment:* yetkileri payment-link:* kodlarını kapsamaz. Panelde API anahtarınızın Yetkiler listesine ihtiyacınız olan payment-link:* kodlarını ekleyin ya da bu iş için yeni bir anahtar oluşturun.
Ortam
Linkin ortamını (TEST ya da LIVE) anahtarınızın ortamı belirler. Gövdede environment göndermeniz gerekmez; gönderirseniz anahtarınızın ortamıyla aynı olmalıdır, aksi hâlde 403 payment_link.environment.mismatch döner. Bir anahtar yalnız kendi ortamındaki linkleri görür ve değiştirir.
İstek
POST /api/v1/payments/links — imzalı istek, yetki payment-link:create.
Idempotency-Key
Zorunludur. 8–200 karakter, boşluksuz yazdırılabilir ASCII (^[\x21-\x7E]{8,200}$). Linki tanımlayan bir değer kullanın — ör. plink-INV-2026-0042.
- Aynı anahtar + aynı gövde → yeni link oluşturulmaz; bu anahtarla oluşturulmuş link
200vereplayed: trueile döner. Ağ zaman aşımında güvenle tekrar deneyebilirsiniz. - Aynı anahtar + farklı gövde →
409 payment_link.idempotency.conflict. - Anahtar yoksa
400 payment_link.idempotency.key_required, biçim dışıysa400 payment_link.idempotency.key_invalid.
Alanlar
Tanımlanmamış bir alan ya da yanlış tip 400 VALIDATION_ERROR döner. İş kuralı ihlali (ör. FIXED linkte amountMinor yok) 422 payment_link.validation.invalid döner ve details.errors hangi alanın neden reddedildiğini listeler.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
environment | string | Hayır | TEST | LIVE. Gönderirseniz anahtarınızın ortamıyla aynı olmalı. |
usage | string | Evet | SINGLE_USE | MULTI_USE. Değiştirilemez. |
amountMode | string | Evet | FIXED | OPEN | ITEMIZED. Değiştirilemez. |
currency | string (ISO 4217) | Evet | ör. "TRY". Hesabınızın bu ortamda tanımlı ödeme sağlayıcılarının desteklediği bir birim olmalı; aksi 422 payment_link.currency.unsupported. Değiştirilemez. |
amountMinor | integer | FIXED'de evet | Link tutarı, > 0. |
minAmountMinor | integer | OPEN'da evet | Alıcının girebileceği en az tutar, > 0. |
maxAmountMinor | integer | Hayır | OPEN: en çok tutar, ≥ minAmountMinor. |
suggestedAmountsMinor | integer[] | Hayır | OPEN: en fazla 6 önerilen tutar; artan sırada ve [min, max] aralığında. |
quantityEnabled | boolean | Hayır | Alıcı adet seçer. Yalnız FIXED + MULTI_USE. |
minQuantity, maxQuantity | integer | quantityEnabled'da evet | 1 ≤ minQuantity ≤ maxQuantity ≤ 999. |
items | object[] | ITEMIZED'da evet | 1–50 kalem — aşağıya bakın. |
capacity | integer | Hayır | Yalnız MULTI_USE: satılabilecek toplam birim. Boş = sınırsız. SINGLE_USE'da gönderilirse 422. |
title | string | Evet | 1–120 karakter, düz metin. Sayfa başlığında ve paylaşım kartında görünür. |
description | string | Hayır | En fazla 2000 karakter, düz metin — HTML ve Markdown işlenmez. |
successMessage | string | Hayır | Başarılı ödemeden sonra gösterilen metin, en fazla 500 karakter. |
successRedirectUrl | string | Hayır | Başarılı ödemeden sonra alıcının yönlendirileceği adres. Yalnız https://, en fazla 2048 karakter. |
taxNote | string | Hayır | Tutarın yanındaki not, ör. "KDV dahil", en fazla 80 karakter. |
locale | string | Hayır | Sayfa dili: tr | en. Varsayılan tr. |
startsAt | string (ISO 8601) | Hayır | Bu andan önce ödeme başlatılamaz. Boş = hemen. |
expiresAt | string (ISO 8601) | Hayır | Link bu anda EXPIRED olur. Gelecekte ve startsAt'ten sonra olmalı. Boş = süresiz. |
eventAt | string (ISO 8601) | Hayır | Etkinlik tarihi; yalnız sayfada gösterilir. |
buttonLabelKey | string | Hayır | Ödeme düğmesi metni: PAY | DONATE | BUY | BOOK. Boş = organizasyonunuzun varsayılanı. |
requireTermsAcceptance | boolean | Hayır | true ise alıcı, organizasyonunuzun yasal metin linklerini onaylamadan ödeme yapamaz. |
buyerFields | object | Hayır | Alıcıdan hangi standart bilgilerin isteneceği — aşağıya bakın. |
customFields | object[] | Hayır | En fazla 20 özel alan — aşağıya bakın. |
recipient | object | Hayır | Kişiye özel linkin alıcısı — aşağıya bakın. |
prefill | object | Hayır | Ödeme kaydına yazılacak alıcı bilgileri — aşağıya bakın. |
verification | object | Hayır | Erişim doğrulaması: { "required": true, "channel": "EMAIL" }. required: true ise recipient.email zorunludur. Yalnız EMAIL desteklenir. |
reminders | object | Hayır | { "enabled": true, "intervalHours": 48, "maxCount": 2 } — intervalHours 24–168, maxCount 1–3. Yalnız SINGLE_USE ve recipient doluyken. |
checkout | object | Hayır | Ödeme formunu daraltır — aşağıya bakın. |
reference | string | Hayır | Sizin referansınız (ör. fatura no), en fazla 128 karakter. Alıcıya gösterilmez; listelemede aranabilir. |
tags | string[] | Hayır | En fazla 10 etiket, her biri [a-z0-9_-]{1,32}. |
branchCode, salesChannel, campaign, agentCode | string | Hayır | Atıf alanları (en fazla 64 / 32 / 64 / 32 karakter). Alıcıya gösterilmez. |
merchantNotifyEmails | string[] | Hayır | Ödeme alındığında bildirim e-postası gidecek en fazla 5 adres. |
metadata | object | Hayır | En fazla 20 anahtar; anahtar [A-Za-z0-9_.-]{1,40}, değer en fazla 500 karakterlik string. payment.link.* webhook'larında ve linkin API yanıtlarında geri döner; alıcıya gösterilmez. |
items[]
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
itemKey | string | Hayır | Kalemin kimliği, [A-Za-z0-9_-]{1,64}, link içinde tekil. Boş bırakırsanız sunucu it_… biçiminde üretir. Değiştirilemez — stok sayacı bu anahtara bağlıdır. |
name | string | Evet | 1–120 karakter. |
description | string | Hayır | En fazla 500 karakter. |
unitPriceMinor | integer | Evet | Birim fiyat, > 0. |
minQuantity | integer | Hayır | 0 = alıcı bu kalemi seçmeyebilir. |
maxQuantity | integer | Evet | 1–999. |
capacity | integer | Hayır | Kalem stoğu. Boş = sınırsız. |
buyerFields
Her alan HIDDEN | OPTIONAL | REQUIRED değerlerinden birini alır.
| Alan | Varsayılan | Toplanan bilgi |
|---|---|---|
name | REQUIRED | Ad ve soyad |
email | REQUIRED | E-posta |
phone | OPTIONAL | Telefon (E.164) |
address | HIDDEN | Fatura adresi — adres, şehir, ülke, posta kodu |
identityNumber | HIDDEN | TC kimlik numarası (algoritmik doğrulama) |
customFields[]
| Alan | Tip | Açıklama |
|---|---|---|
key | string | [a-z][a-z0-9_]{0,39}, link içinde tekil. Alıcının cevabı bu anahtarla döner. |
label | string | 1–80 karakter. |
fieldType | string | TEXT | NUMBER | EMAIL | PHONE | DATE | SELECT | CHECKBOX | TCKN | VKN |
required | boolean | Zorunlu alan mı. |
options | string[] | Yalnız SELECT: 1–20 seçenek, her biri 1–80 karakter. |
maxLength | integer | Yalnız TEXT: 1–500 (0 = 200). |
helpText | string | En fazla 200 karakter. |
Cevaplar string olarak saklanır: CHECKBOX için "true" / "false", DATE için YYYY-MM-DD. Dosya yükleme alanı yoktur.
recipient ve prefill
recipient—{ name, email, phone }(ad en fazla 120, e-posta en fazla 180 karakter, telefon E.164). Linki belirli bir kişiye gönderiyorsanız doldurun:POST /:id/sendve hatırlatmalar varsayılan olarak bu adrese gider, erişim doğrulama kodu yalnız bu e-postaya gönderilir. Ödeme sayfasında yalnız maskeli hâli görünür.prefill—{ name, surname, email, phone, identityNumber, address, city, country, zipCode }(countryISO 3166-1 alpha-2). Bu bilgiler alıcının tarayıcısına gönderilmez; ödeme kaydının alıcı bilgilerine sunucuda yazılır. Alıcının formda girdiği değerler yalnız boş kalan alanları doldurur. Linke erişim doğrulaması eklediyseniz, doğrulamayı geçen alıcı bu bilgileri formda görür —identityNumberhariç.
Her iki nesne de şifreli saklanır ve yalnız sizin API yanıtlarınızda açık döner.
checkout
| Alan | Tip | Açıklama |
|---|---|---|
requireThreeDs | boolean | true ise bu linkteki ödemeler 3D Secure ile yapılır. Yalnız sıkılaştırır; OPEN ve MULTI_USE linklerde 3D Secure zaten zorunludur. |
paymentMethods | string[] | Ödeme formunda gösterilecek yöntemler, ör. ["card"]. Panelinizdeki form ayarlarının alt kümesi olmalıdır; boş = form ayarları. |
Örnek istek
# OpenSSL 3.0+ gerekir. Gövde boşluksuz JSON olmalıdır.
KEY_ID="mk_test_sk_..." # X-Key-Id
KEY_FILE="lunixi-signing.key" # Ed25519 özel anahtarınız (PEM)
REQ_PATH="/api/v1/payments/links"
BODY='{"usage":"SINGLE_USE","amountMode":"FIXED","currency":"TRY","amountMinor":150000,"title":"Kasım danışmanlık bedeli","expiresAt":"2026-10-31T20:59:59.000Z","reference":"INV-2026-0042","recipient":{"name":"Ayşe Yılmaz","email":"[email protected]"},"metadata":{"crmId":"A-77"}}'
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
NONCE=$(openssl rand -hex 16)
DIGEST="SHA-256=$(printf '%s' "$BODY" | openssl dgst -sha256 -binary | base64)"
printf 'POST\n%s\nX-Date:%s\nX-Nonce:%s\nDigest:%s' "$REQ_PATH" "$DATE" "$NONCE" "$DIGEST" > canonical.txt
SIGNATURE=$(openssl pkeyutl -sign -inkey "$KEY_FILE" -rawin -in canonical.txt | base64 | tr -d '\n')
curl -X POST "https://api-gateway.lunixi.com$REQ_PATH" \
-H "Content-Type: application/json" \
-H "X-Key-Id: $KEY_ID" \
-H "X-Date: $DATE" \
-H "X-Nonce: $NONCE" \
-H "Digest: $DIGEST" \
-H "X-Signature: $SIGNATURE" \
-H "Idempotency-Key: plink-INV-2026-0042" \
--data-raw "$BODY"Farklı link tipleri için gövde örnekleri:
// Bağış — alıcı tutarı girer, önerilen tutar düğmeleri
{ "usage": "MULTI_USE", "amountMode": "OPEN", "currency": "TRY",
"minAmountMinor": 5000, "suggestedAmountsMinor": [10000, 25000, 50000],
"title": "Kış kampanyası bağışı", "buttonLabelKey": "DONATE" }
// Bilet — sabit fiyat, adet seçimi, 200 kişilik kapasite
{ "usage": "MULTI_USE", "amountMode": "FIXED", "currency": "TRY",
"amountMinor": 45000, "quantityEnabled": true, "minQuantity": 1, "maxQuantity": 4,
"capacity": 200, "title": "Atölye — 12 Kasım", "eventAt": "2026-11-12T16:00:00.000Z" }
// Kalemli — beden seçimi, kalem başına stok
{ "usage": "MULTI_USE", "amountMode": "ITEMIZED", "currency": "TRY",
"title": "Takım forması",
"items": [
{ "itemKey": "forma_m", "name": "Forma — M", "unitPriceMinor": 90000, "maxQuantity": 3, "capacity": 40 },
{ "itemKey": "forma_l", "name": "Forma — L", "unitPriceMinor": 90000, "maxQuantity": 3, "capacity": 40 }
] }Yanıt
201 Created — tekrar isteğinde 200 OK ve replayed: true.
{
"status": "success",
"code": "SUCCESS",
"data": {
"id": "5f0c1d2e-8a4b-4c6d-9e7f-1a2b3c4d5e6f",
"shortCode": "7KQ2M9XAPT",
"url": "https://pay.lunixi.com/7KQ2M9XAPT",
"organizationId": "b1d2c3e4-…",
"environment": "TEST",
"state": "ACTIVE",
"version": 1,
"rowVersion": 1,
"createdBy": { "type": "API_KEY", "id": "mk_test_sk_…" },
"createdAt": "2026-09-25T09:00:00.000Z",
"updatedAt": "2026-09-25T09:00:00.000Z",
"completedAt": null,
"expiredAt": null,
"deactivatedAt": null,
"takedown": null,
"verificationLocked": false,
"hasActiveAttempt": false,
"amountLocked": false,
"counters": {
"paidCount": 0, "collectedAmountMinor": 0, "refundedAmountMinor": 0,
"soldQuantity": 0, "reservedQuantity": 0, "attemptCount": 0
},
"availability": { "soldOut": false, "remainingQuantity": null, "inProgress": false, "items": [] },
"usage": "SINGLE_USE",
"amountMode": "FIXED",
"currency": "TRY",
"amountMinor": 150000,
"title": "Kasım danışmanlık bedeli",
"expiresAt": "2026-10-31T20:59:59.000Z",
"reference": "INV-2026-0042",
"recipient": { "name": "Ayşe Yılmaz", "email": "[email protected]", "phone": "" },
"metadata": { "crmId": "A-77" },
"replayed": false
},
"statusCode": 201,
"requestId": "req_7f3d9c1a4b2e"
}Yanıt, gönderdiğiniz bütün alanları varsayılanlarıyla birlikte düz olarak içerir (örnekte kısaltıldı). Ayarlanmamış zaman alanları ve isteğe bağlı kimlikler null döner. Linkin kendi alanları:
| Alan | Açıklama |
|---|---|
id | Linkin kimliği (UUID) — diğer bütün uçlarda :id |
shortCode, url | 10 karakterlik kod ve paylaşılacak adres |
environment | TEST | LIVE |
state | ACTIVE | PAUSED | COMPLETED | EXPIRED | DEACTIVATED | TAKEN_DOWN — bkz. Yaşam döngüsü |
version | Linkin geçerli sürümü; her güncellemede artar |
rowVersion | İyimser kilit sayacı; PATCH ve durum işlemlerinde expectedRowVersion olarak geri gönderilir |
createdBy | { type: "USER" | "API_KEY", id } — API ile oluşturulan linkte anahtar kimliği |
completedAt, expiredAt, deactivatedAt | İlgili durum geçişinin zamanı |
takedown | Yalnız TAKEN_DOWN'da: { reasonCode, takenDownAt }; reasonCode ∈ PHISHING, FRAUD, BRAND_IMPERSONATION, PROHIBITED_GOODS, LEGAL_REQUEST, OTHER |
verificationLocked | Erişim doğrulaması çok fazla hatalı deneme nedeniyle kilitlendi; POST /:id/send kilidi açar |
hasActiveAttempt | Şu anda süren bir ödeme var |
amountLocked | Tutar ve kalemler düzenlenemez (süren ödeme var ya da ödeme alınmış) |
counters | paidCount, collectedAmountMinor, refundedAmountMinor, soldQuantity, reservedQuantity (süren ödemelerin tuttuğu birim), attemptCount |
availability | soldOut, remainingQuantity (kapasite yoksa null), inProgress (tek kullanımlıkta başka bir alıcı ödüyor), items[] (itemKey, soldOut, remainingQuantity) |
replayed | true = aynı Idempotency-Key ve aynı gövdeyle yapılan tekrar isteği; kayıtlı link döndü |
Hatalar
Hata zarfı ve code üzerinden dallanma kuralı: Hata Yönetimi.
| Status | Kod | Ne yapmalı |
|---|---|---|
400 | VALIDATION_ERROR | Tanımlanmamış alan ya da yanlış tip; details.errors'daki alanı düzeltin |
400 | payment_link.idempotency.key_required / key_invalid | 8–200 karakterlik bir Idempotency-Key gönderin |
401 | AUTH_HEADERS_MISSING, INVALID_DATE, NONCE_REPLAY, INVALID_KID, DIGEST_MISSING, INVALID_DIGEST, INVALID_SIGNATURE | İmza başlıklarını ve kanonik diziyi kontrol edin — bkz. Kimlik doğrulama |
403 | API_INSUFFICIENT_SCOPE | Anahtarınıza payment-link:create yetkisini ekleyin |
403 | IP_NOT_ALLOWED | İstek IP'si anahtarın izinli IP listesinde değil; panelden ekleyin |
403 | MERCHANT_SUSPENDED | Hesabınız aktif değil; destek ekibiyle iletişime geçin |
403 | PRODUCT_NOT_ENABLED | PAYMENT_GATEWAY aboneliğiniz bu ortamda aktif değil ya da ürün API anahtarınızda tanımlı değil — bkz. PRODUCT_NOT_ENABLED |
403 | payment_link.environment.mismatch | environment alanını kaldırın ya da anahtarınızın ortamını gönderin |
409 | payment_link.idempotency.conflict | Aynı Idempotency-Key farklı bir gövdeyle kullanıldı; yeni link için yeni anahtar üretin |
409 | payment_link.merchant.unavailable | Hesabınız şu anda ödeme alamıyor (hesap ya da ürün erişimi aktif değil); destek ekibiyle iletişime geçin |
422 | payment_link.validation.invalid | details.errors: [{ field, reason }] listesindeki kuralları düzeltin |
422 | payment_link.currency.unsupported | Hesabınızın bu ortamda desteklediği bir para birimi seçin |
503 | PRODUCT_ENTITLEMENT_UNAVAILABLE | Geçici; aynı Idempotency-Key ile tekrar deneyin |
4xx hataları aynı istekle tekrar denenerek düzelmez; önce isteği düzeltin. 5xx yanıtlarında (ör. 503, 504) isteği aynı Idempotency-Key ve aynı gövdeyle üstel geri çekilmeyle yeniden deneyin: link ilk denemede oluşturulduysa ikinci bir link açılmaz, kayıtlı link replayed: true ile döner.
Webhook'lar
Link oluşturulduğunda payment.link.created yayınlanır. Ödeme ve link event'lerinin tamamı: Webhook'lar.
Sonraki adımlar
- Linkleri Yönetme — listeleme, güncelleme, duraklatma, gönderme, QR
- Ödeme Sayfası — alıcının gördüğü sayfa, marka ve erişim doğrulaması
- Webhook'lar —
payment.capturedile siparişi teslim etme