Payment Orchestrator
Senetle Öde

Senetle Öde

paymentMethod: "PROMISSORY_NOTE" ile ödeme tutarı, alıcı adına düzenlenen bir ya da daha fazla elektronik senede bölünür. Senetler sizin bağladığınız senet sağlayıcısındaki kendi hesabınızda, sizin adınıza düzenlenir. Tahsilat vadede borçludan doğrudan sizin hesabınıza yapılır; para Lunixi üzerinden geçmez.

Senetler sağlayıcıda düzenlendiği anda ödeme CAPTURED olur. Alıcının kod girmesi ya da bir sayfaya yönlendirilmesi gerekmez: yanıtta action yoktur.

⚠️

Senetle ödemede CAPTURED, senetlerin düzenlendiği anlamına gelir; paranın tahsil edildiği anlamına gelmez. Her senedin vadedeki sonucu ayrı bildirilir: ödendi (payment.promissory_note.paid), protesto edildi (payment.promissory_note.protested) ya da iptal edildi (payment.promissory_note.cancelled). Bkz. Webhook'lar.

Tüm tutarlar minor unit (kuruş) cinsinden tam sayıdır: "amount": 300000 = ₺3.000,00. Bütün yöntemlerde ortak olan istek, yanıt ve hata kuralları Payment sayfasındadır.

Nasıl çalışır

Senet sağlayıcınızı bağlayın (bir kez)

Panelde senet sağlayıcınızı bağlayın, bağlantı ayarlarını girin ve Ödeme → Form Ayarları ekranında Senetle Öde yöntemini açın. Bkz. Ön koşullar.

Ödemeyi başlatın

Ödemeyi Checkout Formu ile ya da sunucunuzdan Direct API ile başlatın. İstekte vade planını siz verirsiniz ya da senet sayısını alıcı seçer; borçlu bilgileri sağlayıcının istediği alanlarla gönderilir.

Senetler düzenlenir

Sağlayıcı senetleri anında düzenler. Ödeme CAPTURED olur ve payment.captured webhook'u gelir. Senetlerin seri numaraları, tutarları ve vadeleri senet listesinde yer alır.

Vadeleri izleyin

Senetlerin durumu sağlayıcıdan düzenli aralıklarla okunur. Bir senet ödendiğinde, protesto edildiğinde ya da iptal edildiğinde ilgili webhook gelir. Bkz. Durum güncellemeleri.

Ön koşullar

Sağlayıcı bağlantısı

Senetler sağlayıcıdaki kendi hesabınızda düzenlendiği için önce sağlayıcıda bir hesabınızın olması gerekir. Panelde sağlayıcıyı bağlarken sağlayıcı hesabınızın API anahtarını ve aşağıdaki ayarları girersiniz. Ayarlar düzenlenen her senede uygulanır.

AyarDeğerAçıklama
Senedin düzenlendiği il81 ilden biriSenette düzenleme yeri olarak yazılır
Belge türüBono (senet) ya da Ödeme emriDüzenlenecek belgenin türü. Senet listesinde documentType: PROMISSORY_NOTE ya da PAYMENT_ORDER
Bedel türüBorç karşılığı ya da Hizmet karşılığıSenedin hangi bedel karşılığında düzenlendiği
Senet devredilebilirAçık / kapalıKapalıysa senet ciro edilemez
En az ve en çok senet sayısı1–24Bir ödemedeki senet sayısının sınırları. Alıcıya sunulan senet sayısı seçenekleri ve sizin gönderdiğiniz vade planının satır sayısı bu aralıkta olmalıdır
Vadeler arası ay1–12Plan senet sayısından üretildiğinde ardışık iki vade arasındaki ay sayısı
İlk vade (gün sonra)1–365Plan senet sayısından üretildiğinde ilk vadenin düzenleme gününden kaç gün sonra olacağı
Test ortamıAçık / kapalıSenetleri sağlayıcının test ortamında düzenler

Son iki ayar yalnız senet sayısıyla üretilen planı etkiler; vade planını kendiniz gönderdiğinizde sizin tarihleriniz kullanılır.

Yöntemi açma

  • Panelde Ödeme → Form Ayarları ekranında Senetle Öde yöntemini açın ve bağladığınız sağlayıcıyı seçin. Panelde kapalı yöntem her kanalda kapalıdır: formda gösterilmez, yöntem listesinde yer almaz ve Direct API ile de başlatılamaz (422 payment.method.disabled).
  • Yöntem açık ve sağlayıcısı bağlıysa GET /payments/methods yanıtında PROMISSORY_NOTE satırı yer alır. Sağlayıcının bağlantı ayarları okunamazsa sağlayıcı bu listede gösterilmez ve ödeme 422 payment.provider.not_available alır.
  • Para birimi TRY'dir. Senetle ödeme ön provizyonu desteklemez; preauth: true ile istek ödeme başlamadan 422 payment.preauth.unsupported_for_method alır.

Yöntem satırı

GET /payments/methods yanıtındaki satır, alıcıdan istenecek alanları providers[].inputFields içinde taşır. Aşağıdaki çıktı kısaltılmıştır:

{
  "paymentMethod": "PROMISSORY_NOTE",
  "category": "OFFLINE",
  "blockName": "promissoryNote",
  "displayName": "Senetle Öde",
  "providerSelection": "OPTIONAL",
  "providerSelectionMode": "PLATFORM",
  "actionTypes": [],
  "currencies": ["TRY"],
  "preauth": false,
  "providers": [
    {
      "providerCode": "<providerCode>",
      "displayName": "<sağlayıcının görünen adı>",
      "actionTypes": [],
      "preauth": false,
      "inputFields": [
        {
          "key": "noteCount",
          "type": "SELECT",
          "required": false,
          "label": { "tr": "Senet sayısı", "en": "Number of notes" },
          "options": [
            { "value": "1", "label": { "tr": "1 senet", "en": "1 note" } },
            { "value": "2", "label": { "tr": "2 senet", "en": "2 notes" } },
            { "value": "3", "label": { "tr": "3 senet", "en": "3 notes" } }
          ],
          "requiredWhen": null,
          "itemFields": [],
          "minItems": null,
          "maxItems": null
        },
        {
          "key": "debtorType",
          "type": "SELECT",
          "required": true,
          "label": { "tr": "Borçlu türü", "en": "Debtor type" },
          "options": [
            { "value": "INDIVIDUAL", "label": { "tr": "Bireysel", "en": "Individual" } },
            { "value": "CORPORATE", "label": { "tr": "Kurumsal", "en": "Corporate" } }
          ]
        },
        { "key": "identityNumber", "type": "TCKN", "required": true, "prefill": "buyer.identityNumber", "pii": true },
        { "key": "address", "type": "ADDRESS", "required": true, "pii": true },
        {
          "key": "taxNumber",
          "type": "VKN",
          "required": false,
          "pii": true,
          "requiredWhen": { "field": "debtorType", "equals": "CORPORATE" }
        },
        {
          "key": "guarantors",
          "type": "GROUP",
          "required": false,
          "pii": true,
          "maxItems": 5,
          "itemFields": [
            { "key": "identityNumber", "type": "TCKN", "required": true },
            { "key": "name", "type": "TEXT", "required": true, "maxLength": 100 }
          ]
        }
      ]
    }
  ]
}

<providerCode> bir yer tutucudur. Sağlayıcı kodunu, alan listesini, seçenekleri ve sınırları her zaman bu yanıttan okuyun; uygulamanıza sabit yazmayın. Alan tanımının bütün özellikleri ve tipleri: Payment — Yöntem alanları.

Vade planı

Her ödemenin bir vade planı vardır: kaç senet düzenleneceği, her senedin tutarı ve vadesi. Plan iki yoldan biriyle belirlenir:

KaynakAlanKim belirler
Açık planschedule: { "amount", "dueDate" } satırlarından oluşan listeSiz. Direct API'de istekte, Checkout Formu'nda intent'te gönderilir
Senet sayısınoteCount: inputFields içindeki noteCount seçeneklerinden biri ("1", "2" …)Direct API'de siz, Checkout Formu'nda alıcı

Plan kuralları

  • Satır sayısı en az 1, en çok 24'tür ve bağlantı ayarınızdaki en az / en çok senet sayısı aralığında olmalıdır.
  • amount kuruş cinsinden tam sayıdır ve en az 1'dir. Satırların toplamı ödemenin amount değerine eşit olmalıdır.
  • dueDate YYYY-MM-DD biçimindedir ve İstanbul takvimine göre bugünden sonra olmalıdır. Satırlar vadeye göre artan sırada gönderilir; aynı güne iki senet olabilir. En geç vade bugünden 10 yıl sonrasıdır.
  • Satırlarda amount ve dueDate dışında alan bulunmaz.

Planın yapısı (boş olmayan liste, en çok 24 satır, satırda yalnız amount ve dueDate, tam sayı tutar, YYYY-MM-DD biçimi) istek doğrulamasında denetlenir; uymayan istek 400 VALIDATION_ERROR alır. Toplam, tarihlerin geleceğe ve sıraya uygunluğu ve bağlantı ayarınızın sınırları 400 payment.method.block_invalid ile döner; sebepler aşağıdadır.

Senet sayısından plan

noteCount gönderildiğinde plan şöyle üretilir:

  • Tutar senetlere eşit bölünür; bölünmeden artan kuruş son senede eklenir. Örneğin 100001 kuruş ve 3 senet: 33333, 33333, 33335.
  • İlk vade, düzenleme gününe bağlantı ayarındaki İlk vade (gün sonra) eklenerek bulunur. Sonraki vadeler Vadeler arası ay aralığıyla gelir. Ayın son gününü aşan gün o ayın son gününe çekilir (31 Ocak + 1 ay = Şubat'ın son günü).
  • noteCount değerleri GET /payments/methods yanıtındaki seçeneklerdir ve bağlantı ayarınızdaki en az / en çok senet sayısından üretilir. Seçenek dışındaki bir değer ya da senet sayısından küçük bir tutar invalid_option alır.

inputFields içindeki noteCount alanında required değeri false'tur, çünkü planı schedule ile de verebilirsiniz. Plan vermediğiniz her ödemede noteCount zorunludur.

Checkout Formu ile

Formda senetle ödemenin çağrılarını Checkout Form SDK'sı yapar. Sizin yazacağınız kod, kartla ödemedeki gibi sunucunuzda intent oluşturmak ve formu sayfanıza mount etmektir → Checkout Formu.

Intent alanları

POST /payments/intents gövdesine iki isteğe bağlı alan eklenir:

AlanTipAçıklama
paymentMethodstring"PROMISSORY_NOTE": ödeme senede sabitlenir; form doğrudan Senetle Öde ile açılır ve alıcı başka yöntem seçemez
promissoryNote.schedulearraySizin vade planınız: [{ "amount": …, "dueDate": "YYYY-MM-DD" }]. Verirseniz formda plan gösterilir ve alıcı senet sayısı seçmez. Vermezseniz alıcı senet sayısını seçer
{
  "amount": 300000,
  "currency": "TRY",
  "orderId": "ORDER-1003",
  "callbackUrl": "https://merchant.example.com/payment/callback",
  "paymentMethod": "PROMISSORY_NOTE",
  "promissoryNote": {
    "schedule": [
      { "amount": 100000, "dueDate": "2026-11-15" },
      { "amount": 100000, "dueDate": "2026-12-15" },
      { "amount": 100000, "dueDate": "2027-01-15" }
    ]
  }
}
  • Intent oluşturulurken plan, plan kurallarının bağlantı ayarından bağımsız olanlarıyla denetlenir: yapı, tutar toplamı, tarihler, sıra ve en çok 24 satır. Geçersiz plan intent'i açmadan reddedilir: yapı hatası 400 VALIDATION_ERROR, kural hatası 400 payment.method.block_invalid alır; alan yolu promissoryNote.schedule[2].dueDate biçimindedir.
  • Bağlantı ayarınızdaki en az / en çok senet sayısı, alıcı ödemeyi başlattığında denetlenir. Planınız bu aralıkta değilse form ödemeyi başlatmaz; alan yolu promissoryNoteSchedule'dır.
  • Planı başka bir yönteme sabitlenmiş intent'te gönderirseniz (ör. "paymentMethod": "WALLET") istek 400 payment.method.block_invalid alır; sebep not_allowed_for_ önekiyle yöntem kodunu taşır (ör. not_allowed_for_WALLET).
  • Intent'te paymentMethod göndermezseniz alıcı Senetle Öde'yi formdaki diğer açık yöntemler arasından seçer. Gösterilecek yöntemleri settings.paymentMethods ile daraltabilirsiniz; Senetle Öde'nin grubu promissory_note'tur.

Alıcının gördüğü adımlar

Yöntemi seçer

Alıcı ödeme yöntemleri arasından Senetle Öde'yi seçer. Intent'i "paymentMethod": "PROMISSORY_NOTE" ile oluşturduysanız form doğrudan bu adımla açılır.

Planı görür ya da senet sayısını seçer

Intent'te plan verdiyseniz form senet sayısını, her senedin tutarını ve vadesini gösterir. Vermediyseniz alıcı bağlantı ayarınızdaki sınırlar içinde senet sayısını seçer.

Borçlu bilgilerini girer

Form sağlayıcının istediği alanları gösterir: borçlu türü, T.C. kimlik numarası, ad, soyad, doğum tarihi, e-posta, cep telefonu ve adres. Kurumsal borçluda şirket unvanı ve vergi kimlik numarası da istenir; kefil eklemek isteğe bağlıdır. Intent'te gönderdiğiniz buyer bilgileri ilgili alanlara önceden doldurulur.

Sonucu görür

Senetler düzenlenince form başarı mesajı gösterir. Bir alan hatalıysa form hatayı alanın altında gösterir; sağlayıcı borçluyu reddederse form bunu söyler.

Formun çağrısı — POST /payments/form/payment

Bu bölüm başvuru içindir; çağrıyı SDK yapar. Alanlar Checkout Formu — Payment sayfasındakiyle aynıdır; senette blok promissoryNote'tur:

{
  "token": "eyJhbGciOi…",
  "paymentMethod": "PROMISSORY_NOTE",
  "promissoryNote": {
    "providerCode": "<providerCode>",
    "noteCount": "3",
    "debtorType": "INDIVIDUAL",
    "identityNumber": "10000000146",
    "name": "Ayşe",
    "surname": "Yılmaz",
    "birthDate": "1990-01-31",
    "email": "[email protected]",
    "gsmNumber": "+905321234567",
    "address": { "provinceCode": "06", "districtCode": "<districtCode>", "neighborhoodCode": "<neighborhoodCode>", "line": "Örnek Sokak No: 1 Daire: 2" }
  },
  "browserFingerprint": "…",
  "paymentChannel": "WEB"
}
  • Tarayıcı vade planı (schedule) gönderemez; gönderilirse istek 400 payment.method.block_invalid alır, sebep not_allowed_for_form.
  • Intent'te plan verdiyseniz noteCount gönderilmez (not_applicable); vermediyseniz zorunludur.

Direct API ile

POST https://api-gateway.lunixi.com/api/v1/payments/direct/payment
Content-Type: application/json

İstek Step-Up kimlik doğrulaması (Bearer token ve Ed25519 imza başlıkları; bkz. Kimlik Doğrulama) ve zorunlu Idempotency-Key başlığı (en fazla 200 karakter) taşır; kurallar Payment — Idempotency ile aynıdır.

Yöntem alanları

AlanTipZorunluAçıklama
paymentMethodstringEvetPROMISSORY_NOTE
promissoryNoteobjectEvetSenet bloğu; alanları aşağıdaki satırlardadır
promissoryNote.schedulearraynoteCount yoksaVade planı: { "amount", "dueDate" } satırları. Bkz. Plan kuralları
promissoryNote.noteCountstringschedule yoksaSenet sayısı; inputFields içindeki noteCount seçeneklerinden biri. Bkz. Senet sayısından plan
promissoryNote.providerCodestringHayırSağlayıcı kodu (GET /payments/methods). Senetle Öde'de sağlayıcıyı platform seçer (providerSelectionMode: PLATFORM): göndermezseniz platform bağlı sağlayıcılardan birini senet düzenlenmeden önce seçer, gönderirseniz o sağlayıcı kullanılır. Bkz. Sağlayıcı seçimi
promissoryNote.<alan>—Tanıma göreSağlayıcının inputFields tanımındaki borçlu ve kefil alanları; bkz. Borçlu ve kefil alanları. Tanımda olmayan alan gönderilemez
  • schedule ve noteCount'tan yalnız biri gönderilir. İkisi birlikte gönderilirse istek 400 payment.method.block_invalid alır (promissoryNote.noteCount, not_applicable); ikisi de yoksa promissoryNote.noteCount, required.
  • Gövdede yalnız promissoryNote bloğu bulunur: başka bir yöntemin bloğu ya da card, force3D, installment, installmentQuoteToken gönderilirse istek 400 VALIDATION_ERROR alır.
  • Sipariş alanları (orderId, amount, currency, buyer, basketItems …) bütün yöntemlerde aynıdır → Payment — Sipariş alanları. buyer alanları borçlu alanlarının prefill kaynağıdır.

Örnek istek

# Step-Up imza başlıklarının nasıl hesaplandığı için Kimlik Doğrulama sayfasına bakın.
curl -X POST https://api-gateway.lunixi.com/api/v1/payments/direct/payment \
  -H "Authorization: Bearer at_test_5f3e2b1a..." \
  -H "Content-Type: application/json" \
  -H "X-Key-Id: mk_test_sk_..." \
  -H "X-Date: 2026-10-12T09:00:00.000Z" \
  -H "X-Nonce: 3c7a9e2f-5b1d-4f6a-8c0e-2d4b6f8a1c3e" \
  -H "Digest: SHA-256=..." \
  -H "X-Signature: ..." \
  -H "Idempotency-Key: ORDER-1003-1" \
  -d '{
    "paymentMethod": "PROMISSORY_NOTE",
    "orderId": "ORDER-1003",
    "amount": 300000,
    "currency": "TRY",
    "buyer": {
      "name": "Ayşe",
      "surname": "Yılmaz",
      "email": "[email protected]",
      "gsmNumber": "+905321234567",
      "identityNumber": "10000000146"
    },
    "promissoryNote": {
      "schedule": [
        { "amount": 100000, "dueDate": "2026-11-15" },
        { "amount": 100000, "dueDate": "2026-12-15" },
        { "amount": 100000, "dueDate": "2027-01-15" }
      ],
      "debtorType": "INDIVIDUAL",
      "birthDate": "1990-01-31",
      "address": {
        "provinceCode": "06",
        "districtCode": "<districtCode>",
        "neighborhoodCode": "<neighborhoodCode>",
        "line": "Örnek Sokak No: 1 Daire: 2"
      },
      "guarantors": [
        {
          "identityNumber": "20000000114",
          "name": "Mehmet",
          "surname": "Demir",
          "birthDate": "1985-06-15",
          "gsmNumber": "+905331234567"
        }
      ]
    }
  }'
  • Örnekte identityNumber, name, surname, email ve gsmNumber bloğa yazılmamıştır; tanımlarındaki prefill ile buyer alanlarından alınır. Bloğa yazarsanız bloktaki değer kullanılır.
  • districtCode ve neighborhoodCode yer tutucudur; değerleri adres sözlüğünden okuyun.
  • Vade planı yerine senet sayısı göndermek için schedule yerine "noteCount": "3" yazın.

Yanıt

Senetler düzenlendiğinde yanıt 200 döner ve ödeme CAPTURED olur:

{
  "status": "success",
  "code": "PAYMENT_CAPTURED",
  "message": "…",
  "data": {
    "paymentId": "5d1e8a3c-7b2f-4c9d-a0e6-3f8b1c2d4e5a",
    "orderId": "ORDER-1003",
    "status": "CAPTURED",
    "paymentMethod": "PROMISSORY_NOTE",
    "providerCode": "<providerCode>"
  },
  "statusCode": 200,
  "requestId": "…"
}
SonuçYanıtNe yapmalı
Senetler düzenlendi200, data.status CAPTUREDSenetleri listeleyin; vadeleri webhook'larla izleyin
Sağlayıcı borçluyu ya da planı reddetti400, data.status FAILEDRet sebebi code içindedir. Bilgileri düzeltip yeni Idempotency-Key ile tekrar deneyin
Sonuç sağlayıcıyla doğrulanıyor202 PAYMENT_PENDING_RECONCILIATIONYeni ödeme başlatmayın; sonuç payment.captured ya da payment.failed ile gelir

Yanıt senetlerin seri numaralarını taşımaz; senetleri GET /payments/{id}/promissory-notes ile okuyun.

Borçlu ve kefil alanları

Borçlu ve kefil bilgileri sağlayıcının inputFields tanımındaki alanlardır ve promissoryNote bloğunda, tanımdaki key adıyla gönderilir. Alanların kendisi sağlayıcıya göre değişebilir; aşağıdaki kurallar her tanım için geçerlidir.

ÖzellikNe yapmalı
required: trueAlanı gönderin. prefill varsa ve alanı göndermezseniz değer buyer alanından alınır
requiredWhenAynı seviyedeki requiredWhen.field alanının değeri requiredWhen.equals ise alan zorunludur; değilse alanı göndermeyin (not_applicable). Örnek: debtorType CORPORATE iken şirket unvanı ve vergi kimlik numarası istenir, INDIVIDUAL iken gönderilmez
type: "GROUP"Alan, nesnelerden oluşan bir listedir. Her öğenin alanları itemFields tanımıdır; öğe sayısı minItems ve maxItems sınırındadır. Örnek: kefiller (guarantors)
type: "ADDRESS"Alan, il, ilçe, mahalle kodu ve açık adresten oluşan bir nesnedir. Kodları adres sözlüğünden okuyun
type: "VKN"10 haneli vergi kimlik numarası; sağlama algoritmasıyla doğrulanır

Bir alan hatalıysa istek 400 payment.method.block_invalid alır. Sorunlu alanın yolu details.field içindedir ve iç içe alanları gösterir: promissoryNote.address.districtCode, promissoryNote.guarantors[1].identityNumber. Gönderdiğiniz değer hata yanıtında yer almaz.

Tanımı okuyup alanın gerekip gerekmediğine karar veren küçük bir yardımcı:

// fields: GET /payments/methods → PROMISSORY_NOTE satırı → providers[i].inputFields
// values: alıcıdan topladığınız değerler, ör. { debtorType: 'CORPORATE', ... }
function isFieldNeeded(field, values) {
  if (field.requiredWhen) {
    return values[field.requiredWhen.field] === field.requiredWhen.equals;
  }
  return field.required;
}
 
function isFieldAllowed(field, values) {
  // requiredWhen koşulu tutmuyorsa alan gönderilmez.
  return !field.requiredWhen || values[field.requiredWhen.field] === field.requiredWhen.equals;
}

Borçlu ve kefil değerleri yalnız sağlayıcıya iletilir; ödeme kaydında saklanmaz, loglanmaz ve yanıtlarda ya da webhook'larda dönmez.

Senetleri listeleme

GET https://api-gateway.lunixi.com/api/v1/payments/{paymentId}/promissory-notes
Authorization: Bearer at_test_…

Ödemenin senetlerini, tutarlarını, vadelerini ve güncel durumlarını döner. Bearer token ile birlikte Kimlik Doğrulama sayfasındaki imza başlıklarını gönderin. Uç hesabınızda Payment Gateway ürününün açık olmasını ister.

{
  "status": "success",
  "code": "SUCCESS",
  "message": "…",
  "data": {
    "paymentId": "5d1e8a3c-7b2f-4c9d-a0e6-3f8b1c2d4e5a",
    "providerCode": "<providerCode>",
    "documentType": "PROMISSORY_NOTE",
    "rowSerialNumber": "ROW-0000418",
    "currency": "TRY",
    "totalAmount": 300000,
    "notes": [
      {
        "serialNumber": "NOTE-0000418-1",
        "sequence": 1,
        "amount": 100000,
        "dueDate": "2026-11-15",
        "status": "PAID",
        "paidAt": "2026-11-15T10:24:00.000Z",
        "protestedAt": null,
        "cancelledAt": null
      },
      {
        "serialNumber": "NOTE-0000418-2",
        "sequence": 2,
        "amount": 100000,
        "dueDate": "2026-12-15",
        "status": "ISSUED",
        "paidAt": null,
        "protestedAt": null,
        "cancelledAt": null
      },
      {
        "serialNumber": "NOTE-0000418-3",
        "sequence": 3,
        "amount": 100000,
        "dueDate": "2027-01-15",
        "status": "ISSUED",
        "paidAt": null,
        "protestedAt": null,
        "cancelledAt": null
      }
    ]
  },
  "statusCode": 200,
  "requestId": "…"
}
AlanTipAçıklama
paymentIdstringÖdeme kimliği
providerCodestringSenetleri düzenleyen sağlayıcının kodu
documentTypestringPROMISSORY_NOTE (bono) ya da PAYMENT_ORDER (ödeme emri); bağlantı ayarınızdaki belge türü
rowSerialNumberstringBu ödemede birlikte düzenlenen senetlerin ortak seri numarası
currencystringPara birimi
totalAmountintegerSenetlerin toplamı, minor unit
notes[].serialNumberstringSenedin seri numarası; iptalde kullanılır
notes[].sequenceintegerSenedin plandaki sırası, 1'den başlar
notes[].amountintegerSenedin tutarı, minor unit
notes[].dueDatestringVade, YYYY-MM-DD
notes[].statusstringSenedin durumu; aşağıdaki tabloya bakın
notes[].paidAt, protestedAt, cancelledAtstring | nullİlgili durumun gerçekleştiği an (ISO 8601); gerçekleşmediyse null
statusAnlamı
ISSUEDSenet düzenlendi, vadesi bekleniyor
PAIDSenet ödendi; tutar sağlayıcı hesabınıza tahsil edildi
PROTESTEDSenet ödenmedi ve protesto edildi
CANCELLEDSenet iptal edildi

PAID, PROTESTED ve CANCELLED son durumlardır; bir senet bunlardan birine geçtikten sonra değişmez. Senet ödemesi olmayan ya da başka hesaba ait bir ödeme için uç 404 payment.promissory_note.not_found döner.

Senetleri iptal etme

POST https://api-gateway.lunixi.com/api/v1/payments/{paymentId}/promissory-notes/cancel
Content-Type: application/json

Verdiğiniz senetleri ya da ödemenin açık bütün senetlerini sağlayıcıda iptal eder. Bearer token ile birlikte Kimlik Doğrulama sayfasındaki imza başlıklarını gönderin. İptal yetkisi (payment:void) olmayan anahtar 403 alır.

AlanTipZorunluAçıklama
serialNumbersstring[]Hayırİptal edilecek senetlerin seri numaraları; en fazla 24. Gönderilmezse ödemenin ISSUED durumundaki bütün senetleri iptal edilir
{ "serialNumbers": ["NOTE-0000418-2", "NOTE-0000418-3"] }

Yanıt senet listesiyle aynı alanları ve ek olarak senet başına sonucu taşır:

{
  "status": "success",
  "code": "SUCCESS",
  "message": "…",
  "data": {
    "paymentId": "5d1e8a3c-7b2f-4c9d-a0e6-3f8b1c2d4e5a",
    "providerCode": "<providerCode>",
    "documentType": "PROMISSORY_NOTE",
    "rowSerialNumber": "ROW-0000418",
    "currency": "TRY",
    "totalAmount": 300000,
    "notes": [ "…" ],
    "cancelResults": [
      { "serialNumber": "NOTE-0000418-2", "result": "CANCELLED", "errorCode": null },
      { "serialNumber": "NOTE-0000418-3", "result": "CANCELLED", "errorCode": null }
    ]
  },
  "statusCode": 200,
  "requestId": "…"
}
cancelResults[].resultAnlamıNe yapmalı
CANCELLEDSenet iptal edildi; payment.promissory_note.cancelled gönderilir—
ALREADY_CLOSEDSenet zaten ödenmiş, protesto edilmiş ya da iptal edilmiş; dokunulmadıGüncel durumu notes[] içinde okuyun
NOT_CANCELLABLESağlayıcı senedin iptaline izin vermedi (ör. senet tahsil edilmiş). errorCode: payment.promissory_note.not_cancellableSenet iptal edilemez
FAILEDİptal yapılamadı; sebep errorCode içindedirpayment.promissory_note.provider_unavailable ise daha sonra aynı seri numarasıyla tekrar deneyin; payment.promissory_note.cancel_rejected ise tekrar denemeyin
  • İptal ödemenin durumunu değiştirmez: ödeme CAPTURED kalır, senet CANCELLED olur. Para Lunixi üzerinden geçmediği için iade edilecek bir tutar yoktur.
  • Her senet ayrı denenir; birinin başarısız olması diğerlerini durdurmaz. Sonucu her senet için cancelResults içinde okuyun. Bu ödemeye ait olmayan bir seri numarası sonuçta yer almaz.
  • errorCode yalnız NOT_CANCELLABLE ve FAILED sonuçlarında doludur, diğer sonuçlarda null'dır. Değerleri aşağıdaki Lunixi kodlarıdır; result ile birlikte bunlara göre dallanabilirsiniz:
errorCoderesultAnlamı ve ne yapmalı
payment.promissory_note.not_cancellableNOT_CANCELLABLESenet tahsil edilmiş ya da sağlayıcı senedin silinmesine izin vermiyor. Senet iptal edilemez
payment.promissory_note.provider_unavailableFAILEDSağlayıcıya şu anda ulaşılamıyor; geçici bir durumdur. Bir süre sonra aynı seri numarasıyla tekrar deneyin
payment.promissory_note.cancel_rejectedFAILEDSağlayıcı iptali kalıcı olarak reddetti. Aynı istekle tekrar denemek sonucu değiştirmez

Senet belgesi (PDF)

GET https://api-gateway.lunixi.com/api/v1/payments/{paymentId}/promissory-notes/document?locale=tr-TR
Authorization: Bearer at_test_…

Ödemenin senetlerini basılabilir PDF olarak döner; her senet bir sayfadadır. Bearer token ile birlikte imza başlıklarını gönderin. Yanıt Content-Type: application/pdf ile bir dosya indirmesidir, ortak JSON zarfı kullanılmaz.

SorguDeğerAçıklama
localetr-TR ya da en-GBBelgenin dili; verilmezse tr-TR
  • Belge her istekte sağlayıcının güncel verisinden üretilir ve saklanmaz. Kendi arşivinize almak isterseniz indirdiğiniz dosyayı saklayın.
  • Sağlayıcıdan veri şu anda alınamıyorsa uç 503 payment.promissory_note.document_unavailable döner; bir süre sonra tekrar deneyin.

Durum güncellemeleri

Senetlerin durumu sağlayıcıdan düzenli aralıklarla okunur; değişiklik anlık değildir. Bir senedin ödendiği, protesto edildiği ya da sağlayıcı tarafında iptal edildiği, bir sonraki okumada senet listesine ve webhook'lara yansır.

Senedin vadesine göreOkuma sıklığı
Vadeye 7 günden fazla varHaftada bir
Vadenin 7 gün öncesinden 30 gün sonrasına kadarGünde bir
Vadenin üzerinden 30 günden fazla geçtiHaftada bir
  • Webhook'larınıza güvenin; senet listesini sık aralıklarla sorgulamanız gerekmez. Mutabakat için günde bir okuma yeterlidir.
  • İptal ucuyla yaptığınız iptal sağlayıcıdan onay gelir gelmez yansır ve webhook'u hemen gönderilir.

Webhook'lar

EventNe zaman
payment.capturedSenetler düzenlendi; ödeme CAPTURED. Para henüz tahsil edilmedi; tahsilat vadede sağlayıcı hesabınıza yapılır
payment.failedSenetler düzenlenemedi; ödeme FAILED
payment.promissory_note.paidBir senet ödendi
payment.promissory_note.protestedBir senet ödenmedi ve protesto edildi
payment.promissory_note.cancelledBir senet iptal edildi

Senet olayları her senet ve durum için bir kez gönderilir; ödemenin durumunu değiştirmez (data.status CAPTURED kalır). Senede ait alanlar data.promissoryNote içindedir:

{
  "id": "8e2b4d6f-…",
  "type": "payment.promissory_note.paid",
  "data": {
    "intentId": "5d1e8a3c-7b2f-4c9d-a0e6-3f8b1c2d4e5a",
    "merchantId": "m_…",
    "orderId": "ORDER-1003",
    "currency": "TRY",
    "status": "CAPTURED",
    "paymentMethod": "PROMISSORY_NOTE",
    "providerCode": "<providerCode>",
    "promissoryNote": {
      "serialNumber": "NOTE-0000418-1",
      "sequence": 1,
      "amountMinor": "100000",
      "dueDate": "2026-11-15",
      "status": "PAID",
      "occurredAt": "2026-11-15T10:24:00.000Z"
    }
  }
}
AlanAçıklama
data.promissoryNote.serialNumberSenedin seri numarası
data.promissoryNote.sequenceSenedin plandaki sırası
data.promissoryNote.amountMinorSenedin tutarı, minor unit string
data.promissoryNote.dueDateVade, YYYY-MM-DD
data.promissoryNote.statusPAID, PROTESTED ya da CANCELLED
data.promissoryNote.occurredAtDurumun gerçekleştiği an (ISO 8601)

Olaylar kişisel veri taşımaz. Panelde webhook aboneliği oluştururken bu olaylar Senetle Ödeme grubundadır. Teslimat, imza doğrulama ve tekrar deneme kuralları → Webhook'lar.

İade, iptal ve ön provizyon

  • Senetle ödemede iade yapılmaz, tam ya da kısmi. Para Lunixi üzerinden geçmediği için iade edilecek bir tutar yoktur. Alıcıdan tahsilat yapılmasını istemiyorsanız açık senetleri iptal edin.
  • Tahsil edilmiş (PAID) senet iptal edilemez. Tahsil edilmiş bir tutarın geri ödemesi Lunixi üzerinden yapılmaz.
  • Ödemenin kendisi void ile iptal edilmez; iptal senet başınadır.
  • Ön provizyon desteklenmez (bkz. Yöntemi açma).

Hatalar

Hata yanıtları ortak hata zarfını kullanır; message'a göre değil code'a göre dallanın → Hata Yönetimi.

DurumYanıtNe yapmalı
Planın ya da bloğun yapısı bozuk (liste değil, 24'ten fazla satır, tutar tam sayı değil, tarih biçimi yanlış)400 VALIDATION_ERRORdetails.errors[] içindeki alanı düzeltin
Plan, senet sayısı ya da borçlu alanı kurallara uymuyor400 payment.method.block_invaliddetails.field alanını düzeltin; sebepler aşağıda
Yöntem panelde kapalı422 payment.method.disabledYöntemi Ödeme → Form Ayarları'ndan açın
providerCode yok ve bağlı sağlayıcıların hiçbiri ödemeyi karşılamıyor422 payment.provider.none_eligibledetails.candidates alanındaki sonuçlara bakın; sağlayıcıyı promissoryNote.providerCode ile kendiniz seçebilirsiniz
Sağlayıcı bağlı değil ya da bağlantı ayarları okunamıyor422 payment.provider.not_availableSağlayıcı bağlantısını ve ayarlarını panelde kontrol edin
preauth: true gönderildi422 payment.preauth.unsupported_for_methodpreauth olmadan gönderin
Sağlayıcı borçluyu ya da planı reddetti400, ödeme FAILEDBilgileri düzeltin; yeni deneme için yeni Idempotency-Key kullanın
Ödemenin senedi yok404 payment.promissory_note.not_foundpaymentId değerini kontrol edin
Senet belgesi alınamıyor503 payment.promissory_note.document_unavailableBir süre sonra tekrar deneyin
İptal yetkisi yok403İptali payment:void yetkisi olan anahtar ya da kullanıcıyla yapın

Plan ve alan hatalarının sebepleri

payment.method.block_invalid yanıtında sebep details.reason içindedir; bütün ihlaller details.errors[] listesindedir ({ "field", "reason" }).

details.reasonAnlamı
requiredZorunlu alan, plan ya da noteCount gönderilmedi
not_applicableAlan bu durumda gönderilmemeli: requiredWhen koşulu tutmuyor, ya da plan varken noteCount gönderildi
invalid_typeDeğerin tipi yanlış (ör. noteCount sayı değil, metin alanına true gönderildi)
invalid_formatBiçim hatası: T.C. kimlik ya da vergi kimlik numarasının sağlaması, telefon, e-posta, takvimde olmayan tarih, il kodu
invalid_optionSeçenek dışı değer; senet sayısı bağlantı ayarınızın aralığında değil ya da tutar senet sayısından küçük; adres kodları birbirine bağlı değil
too_short, too_longUzunluk sınırı aşıldı (ör. açık adres en fazla 250 karakter)
too_few_items, too_many_itemsPlan satırı sayısı bağlantı ayarınızın aralığında değil ya da kefil sayısı minItems / maxItems sınırının dışında
sum_mismatchPlan satırlarının toplamı amount'a eşit değil
not_in_futureVade bugün ya da daha önce
beyond_horizonVade bugünden 10 yıldan daha sonra
not_ascendingVadeler artan sırada değil
not_allowed_for_formCheckout Formu çağrısında plan gönderildi; formda plan yalnız intent'ten gelir
not_allowed_for_ + yöntem koduPlan, başka bir yönteme sabitlenmiş intent'te gönderildi
unknown_fieldSağlayıcının tanımında olmayan alan

Örnek alan yolları: promissoryNote.schedule[2].dueDate, promissoryNote.noteCount, promissoryNote.address.districtCode, promissoryNote.guarantors[1].identityNumber, promissoryNoteSchedule (intent'teki planınız formda başlatılırken).

Hata kodları

KodHTTPAnlamı ve ne yapmalı
payment.promissory_note.not_found404Bu ödemeye ait senet yok: ödeme senetle yapılmamış, senetler düzenlenmemiş ya da ödeme başka bir hesaba ait. paymentId değerini kontrol edin
payment.promissory_note.document_unavailable503Senet belgesi şu anda sağlayıcıdan alınamıyor. Bir süre sonra tekrar deneyin

Sonraki adımlar