Payment Orchestrator
Pay by Promissory Note

Promissory Notes

With paymentMethod: "PROMISSORY_NOTE" the payment amount is split into one or more electronic promissory notes issued in the buyer's name. The notes are issued in your own account at the promissory-note provider you connect, on your behalf. At maturity the debtor pays directly into your account; the money does not pass through Lunixi.

The payment becomes CAPTURED as soon as the provider issues the notes. The buyer does not enter a code and is not redirected anywhere: the response carries no action.

⚠️

For promissory notes, CAPTURED means the notes were issued; it does not mean the money has been collected. The outcome of each note at maturity is reported separately: paid (payment.promissory_note.paid), protested (payment.promissory_note.protested) or cancelled (payment.promissory_note.cancelled). See Webhooks.

All amounts are integers in minor units (kuruş): "amount": 300000 = ₺3,000.00. The request, response and error rules shared by every method are on the Payment page.

How it works

Connect your promissory-note provider (once)

Connect your provider in the panel, enter the connection settings and enable the Promissory Notes method on the Payments → Form Settings screen. See Prerequisites.

Start the payment

Start the payment with the Checkout Form or from your server with the Direct API. Either you provide the due-date schedule or the buyer chooses the number of notes; debtor details are sent in the fields the provider asks for.

The notes are issued

The provider issues the notes immediately. The payment becomes CAPTURED and the payment.captured webhook is sent. Serial numbers, amounts and due dates are in the note list.

Track the due dates

Note statuses are read from the provider at regular intervals. When a note is paid, protested or cancelled, the corresponding webhook is sent. See Status updates.

Prerequisites

Provider connection

Because the notes are issued in your own account at the provider, you first need an account with the provider. When you connect the provider in the panel you enter your provider account's API key and the settings below. The settings apply to every note issued.

SettingValueDescription
Province of issueOne of the 81 provincesWritten on the note as the place of issue
Document typePromissory note (bono) or Payment orderType of document issued. In the note list documentType is PROMISSORY_NOTE or PAYMENT_ORDER
Exchange typeAgainst a debt or Against a serviceWhat the note is issued against
TransferableOn / offWhen off, the note cannot be endorsed to someone else
Minimum and maximum number of notes1–24Limits on the number of notes in one payment. The note-count options offered to the buyer and the number of rows in a schedule you send must be within this range
Months between due dates1–12When the schedule is generated from a note count, the number of months between two consecutive due dates
First due date (days after)1–365When the schedule is generated from a note count, how many days after the issue date the first note falls due
Test environmentOn / offIssues the notes in the provider's test environment

The last two settings only affect a schedule generated from a note count; when you send the schedule yourself, your dates are used.

Enabling the method

  • Enable the Promissory Notes method on the Payments → Form Settings screen in the panel and select the provider you connected. A method disabled in the panel is disabled on every channel: it is not shown on the form, it is not in the method list and it cannot be started with the Direct API (422 payment.method.disabled).
  • When the method is enabled and its provider is connected, the GET /payments/methods response contains a PROMISSORY_NOTE row. If the provider's connection settings cannot be read, the provider is left out of this list and the payment gets 422 payment.provider.not_available.
  • The currency is TRY. Promissory notes do not support pre-authorization; a request with preauth: true gets 422 payment.preauth.unsupported_for_method before the payment starts.

Method row

The row in the GET /payments/methods response carries the fields to collect from the buyer in providers[].inputFields. The output below is shortened:

{
  "paymentMethod": "PROMISSORY_NOTE",
  "category": "OFFLINE",
  "blockName": "promissoryNote",
  "displayName": "Senetle Öde",
  "providerSelection": "OPTIONAL",
  "providerSelectionMode": "PLATFORM",
  "actionTypes": [],
  "currencies": ["TRY"],
  "preauth": false,
  "providers": [
    {
      "providerCode": "<providerCode>",
      "displayName": "<provider display name>",
      "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> is a placeholder. Always read the provider code, the field list, the options and the limits from this response; do not hard-code them in your application. All properties and types of a field definition: Payment — Method fields.

Due-date schedule

Every payment has a schedule: how many notes are issued, and the amount and due date of each. The schedule comes from one of two sources:

SourceFieldWho decides
Explicit scheduleschedule: a list of { "amount", "dueDate" } rowsYou. Sent in the request with the Direct API, in the intent with the Checkout Form
Note countnoteCount: one of the noteCount options in inputFields ("1", "2" …)You with the Direct API, the buyer on the Checkout Form

Schedule rules

  • At least 1 and at most 24 rows, and within the minimum / maximum number of notes in your connection settings.
  • amount is an integer in minor units and at least 1. The rows must add up exactly to the payment's amount.
  • dueDate uses YYYY-MM-DD and must be after today in the Istanbul calendar. Rows are sent in ascending due-date order; two notes may fall due on the same day. The latest due date is 10 years from today.
  • A row has no fields other than amount and dueDate.

The structure of the schedule (non-empty list, at most 24 rows, only amount and dueDate in a row, integer amounts, YYYY-MM-DD format) is checked during request validation; a request that does not match gets 400 VALIDATION_ERROR. The total, future and ascending dates and your connection-setting limits are reported with 400 payment.method.block_invalid; the reasons are listed below.

Schedule from a note count

When noteCount is sent, the schedule is generated as follows:

  • The amount is split evenly across the notes; the kuruş left over from the division is added to the last note. For example 100001 kuruş in 3 notes: 33333, 33333, 33335.
  • The first due date is the issue date plus the First due date (days after) setting. The following due dates are spaced by Months between due dates. A day past the end of a month moves to that month's last day (31 January + 1 month = last day of February).
  • The noteCount values are the options in the GET /payments/methods response, generated from the minimum / maximum number of notes in your connection settings. A value outside the options, or an amount smaller than the note count, gets invalid_option.

In inputFields the noteCount field has required: false, because you may provide the schedule with schedule instead. Whenever you do not send a schedule, noteCount is required.

With the Checkout Form

On the form, the Checkout Form SDK makes the promissory-note calls. The code you write is the same as for card payments: create an intent on your server and mount the form on your page → Checkout Form.

Intent fields

Two optional fields are added to the POST /payments/intents body:

FieldTypeDescription
paymentMethodstring"PROMISSORY_NOTE": the payment is pinned to promissory notes; the form opens directly with Promissory Notes and the buyer cannot choose another method
promissoryNote.schedulearrayYour due-date schedule: [{ "amount": …, "dueDate": "YYYY-MM-DD" }]. If you send it, the form shows the schedule and the buyer does not choose a note count. If you do not, the buyer chooses the number of notes
{
  "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" }
    ]
  }
}
  • When the intent is created, the schedule is checked against the schedule rules that do not depend on your connection settings: structure, total, dates, order and at most 24 rows. An invalid schedule is rejected before the intent opens: a structural error gets 400 VALIDATION_ERROR, a rule violation gets 400 payment.method.block_invalid; the field path looks like promissoryNote.schedule[2].dueDate.
  • The minimum / maximum number of notes in your connection settings is checked when the buyer starts the payment. If your schedule is outside that range, the form does not start the payment; the field path is promissoryNoteSchedule.
  • If you send a schedule on an intent pinned to another method (e.g. "paymentMethod": "WALLET"), the request gets 400 payment.method.block_invalid; the reason is not_allowed_for_ followed by the method code (e.g. not_allowed_for_WALLET).
  • If you do not send paymentMethod in the intent, the buyer picks Promissory Notes among the other enabled methods on the form. You can narrow the methods shown with settings.paymentMethods; the group of Promissory Notes is promissory_note.

What the buyer sees

Selects the method

The buyer selects Promissory Notes among the payment methods. If you created the intent with "paymentMethod": "PROMISSORY_NOTE", the form opens directly at this step.

Sees the schedule or chooses the number of notes

If you sent a schedule in the intent, the form shows the number of notes and the amount and due date of each. If you did not, the buyer chooses the number of notes within the limits in your connection settings.

Enters the debtor details

The form shows the fields the provider asks for: debtor type, Turkish ID number, first name, last name, date of birth, e-mail, mobile phone and address. For a corporate debtor the company name and tax number are also requested; adding guarantors is optional. The buyer details you sent in the intent prefill the matching fields.

Sees the result

When the notes are issued, the form shows a success message. If a field is invalid the form shows the error under the field; if the provider rejects the debtor, the form says so.

The form's call — POST /payments/form/payment

This section is for reference; the SDK makes the call. The fields are the same as on Checkout Form — Payment; for promissory notes the block is promissoryNote:

{
  "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"
}
  • The browser cannot send a schedule (schedule); if it does, the request gets 400 payment.method.block_invalid with reason not_allowed_for_form.
  • If you sent a schedule in the intent, noteCount is not sent (not_applicable); otherwise it is required.

With the Direct API

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

The request carries Step-Up authentication (Bearer token and Ed25519 signature headers; see Authentication) and the required Idempotency-Key header (at most 200 characters); the rules are the same as Payment — Idempotency.

Method fields

FieldTypeRequiredDescription
paymentMethodstringYesPROMISSORY_NOTE
promissoryNoteobjectYesPromissory-note block; its fields are in the rows below
promissoryNote.schedulearrayIf no noteCountDue-date schedule: { "amount", "dueDate" } rows. See Schedule rules
promissoryNote.noteCountstringIf no scheduleNumber of notes; one of the noteCount options in inputFields. See Schedule from a note count
promissoryNote.providerCodestringNoProvider code (GET /payments/methods). For promissory notes the platform selects the provider (providerSelectionMode: PLATFORM): if you leave it out, the platform picks one of the connected providers before the notes are issued; if you send it, that provider is used. See Provider selection
promissoryNote.<field>—Per definitionDebtor and guarantor fields from the provider's inputFields definition; see Debtor and guarantor fields. Fields that are not in the definition cannot be sent
  • Send only one of schedule and noteCount. If both are sent the request gets 400 payment.method.block_invalid (promissoryNote.noteCount, not_applicable); if neither is sent, promissoryNote.noteCount, required.
  • The body contains only the promissoryNote block: another method's block or card, force3D, installment, installmentQuoteToken gets 400 VALIDATION_ERROR.
  • The order fields (orderId, amount, currency, buyer, basketItems …) are the same for every method → Payment — Order fields. The buyer fields are the prefill source of the debtor fields.

Example request

# See the Authentication page for how the Step-Up signature headers are computed.
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"
        }
      ]
    }
  }'
  • In the example identityNumber, name, surname, email and gsmNumber are not written in the block; they are taken from the buyer fields through their prefill. If you write them in the block, the block value is used.
  • districtCode and neighborhoodCode are placeholders; read the values from the address dictionary.
  • To send a note count instead of a schedule, write "noteCount": "3" instead of schedule.

Response

When the notes are issued the response is 200 and the payment is CAPTURED:

{
  "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": "…"
}
OutcomeResponseWhat to do
Notes issued200, data.status CAPTUREDList the notes; track the due dates with webhooks
The provider rejected the debtor or the schedule400, data.status FAILEDThe decline reason is in code. Fix the details and retry with a new Idempotency-Key
The result is being verified with the provider202 PAYMENT_PENDING_RECONCILIATIONDo not start a new payment; the result arrives as payment.captured or payment.failed

The response does not carry the notes' serial numbers; read the notes with GET /payments/{id}/promissory-notes.

Debtor and guarantor fields

Debtor and guarantor details are fields in the provider's inputFields definition and are sent in the promissoryNote block under the definition's key. The fields themselves may differ by provider; the rules below apply to every definition.

PropertyWhat to do
required: trueSend the field. If it has a prefill and you omit it, the value is taken from the buyer field
requiredWhenWhen the sibling field requiredWhen.field has the value requiredWhen.equals, the field is required; otherwise do not send it (not_applicable). Example: with debtorType CORPORATE the company name and tax number are requested; with INDIVIDUAL they are not sent
type: "GROUP"The field is a list of objects. Each item's fields are the itemFields definition; the number of items is within minItems and maxItems. Example: guarantors (guarantors)
type: "ADDRESS"The field is an object of province, district and neighbourhood codes and the street address. Read the codes from the address dictionary
type: "VKN"10-digit Turkish tax number; validated with its checksum

An invalid field gets 400 payment.method.block_invalid. The path of the offending field is in details.field and points into nested fields: promissoryNote.address.districtCode, promissoryNote.guarantors[1].identityNumber. The value you sent is never included in the error response.

A small helper that reads the definition and decides whether a field is needed:

// fields: GET /payments/methods → PROMISSORY_NOTE row → providers[i].inputFields
// values: the values you collected from the buyer, e.g. { debtorType: 'CORPORATE', ... }
function isFieldNeeded(field, values) {
  if (field.requiredWhen) {
    return values[field.requiredWhen.field] === field.requiredWhen.equals;
  }
  return field.required;
}
 
function isFieldAllowed(field, values) {
  // When the requiredWhen condition does not hold, the field is not sent.
  return !field.requiredWhen || values[field.requiredWhen.field] === field.requiredWhen.equals;
}

Debtor and guarantor values are only passed to the provider; they are not stored on the payment record, not logged and never returned in responses or webhooks.

Listing the notes

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

Returns the payment's notes with their amounts, due dates and current statuses. Send the Bearer token together with the signature headers from Authentication. The endpoint requires the Payment Gateway product to be active on your account.

{
  "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": "…"
}
FieldTypeDescription
paymentIdstringPayment ID
providerCodestringCode of the provider that issued the notes
documentTypestringPROMISSORY_NOTE (promissory note) or PAYMENT_ORDER (payment order); the document type in your connection settings
rowSerialNumberstringShared serial number of the notes issued together for this payment
currencystringCurrency
totalAmountintegerTotal of the notes, minor units
notes[].serialNumberstringThe note's serial number; used to cancel
notes[].sequenceintegerThe note's position in the schedule, starting at 1
notes[].amountintegerThe note's amount, minor units
notes[].dueDatestringDue date, YYYY-MM-DD
notes[].statusstringThe note's status; see the table below
notes[].paidAt, protestedAt, cancelledAtstring | nullWhen that status occurred (ISO 8601); null if it has not
statusMeaning
ISSUEDThe note was issued and is awaiting its due date
PAIDThe note was paid; the amount was collected into your provider account
PROTESTEDThe note was not paid and was protested
CANCELLEDThe note was cancelled

PAID, PROTESTED and CANCELLED are final; once a note reaches one of them it does not change. For a payment that is not a promissory-note payment, or that belongs to another account, the endpoint returns 404 payment.promissory_note.not_found.

Cancelling notes

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

Cancels the notes you list, or every open note of the payment, at the provider. Send the Bearer token together with the signature headers from Authentication. A key without the void permission (payment:void) gets 403.

FieldTypeRequiredDescription
serialNumbersstring[]NoSerial numbers of the notes to cancel; at most 24. If omitted, every note of the payment in ISSUED status is cancelled
{ "serialNumbers": ["NOTE-0000418-2", "NOTE-0000418-3"] }

The response carries the same fields as the note list plus a result per note:

{
  "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[].resultMeaningWhat to do
CANCELLEDThe note was cancelled; payment.promissory_note.cancelled is sent—
ALREADY_CLOSEDThe note was already paid, protested or cancelled; it was left untouchedRead the current status in notes[]
NOT_CANCELLABLEThe provider did not allow the note to be cancelled (e.g. it has been collected). errorCode: payment.promissory_note.not_cancellableThe note cannot be cancelled
FAILEDThe cancellation could not be done; the reason is in errorCodeFor payment.promissory_note.provider_unavailable, retry later with the same serial number; for payment.promissory_note.cancel_rejected, do not retry
  • Cancelling does not change the payment's status: the payment stays CAPTURED and the note becomes CANCELLED. Because the money did not pass through Lunixi, there is no amount to refund.
  • Each note is tried separately; a failure on one does not stop the others. Read the result of each note in cancelResults. A serial number that does not belong to this payment is not included in the result.
  • errorCode is set only for NOT_CANCELLABLE and FAILED results and is null otherwise. Its values are the Lunixi codes below; you can branch on them together with result:
errorCoderesultMeaning and what to do
payment.promissory_note.not_cancellableNOT_CANCELLABLEThe note has been collected or the provider does not allow it to be deleted. The note cannot be cancelled
payment.promissory_note.provider_unavailableFAILEDThe provider cannot be reached right now; this is temporary. Retry later with the same serial number
payment.promissory_note.cancel_rejectedFAILEDThe provider permanently rejected the cancellation. Retrying the same request will not change the result

Note document (PDF)

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

Returns the payment's notes as a printable PDF, one note per page. Send the Bearer token together with the signature headers. The response is a file download with Content-Type: application/pdf; the common JSON envelope is not used.

QueryValueDescription
localetr-TR or en-GBDocument language; tr-TR if omitted
  • The document is generated from the provider's current data on every request and is not stored. To keep it in your own archive, store the downloaded file.
  • If the data cannot be fetched from the provider right now, the endpoint returns 503 payment.promissory_note.document_unavailable; retry after a while.

Status updates

Note statuses are read from the provider at regular intervals; changes are not real time. A note being paid, protested or cancelled on the provider's side shows up in the note list and the webhooks after the next read.

Relative to the note's due dateRead frequency
More than 7 days before the due dateOnce a week
From 7 days before to 30 days after the due dateOnce a day
More than 30 days after the due dateOnce a week
  • Rely on your webhooks; you do not need to poll the note list frequently. For reconciliation, reading it once a day is enough.
  • A cancellation you make with the cancel endpoint is reflected as soon as the provider confirms it, and its webhook is sent right away.

Webhooks

EventWhen
payment.capturedThe notes were issued; the payment is CAPTURED. The money has not been collected yet; it is collected into your provider account at maturity
payment.failedThe notes could not be issued; the payment is FAILED
payment.promissory_note.paidA note was paid
payment.promissory_note.protestedA note was not paid and was protested
payment.promissory_note.cancelledA note was cancelled

Note events are sent once per note and status and do not change the payment's status (data.status stays CAPTURED). The note's fields are in data.promissoryNote:

{
  "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"
    }
  }
}
FieldDescription
data.promissoryNote.serialNumberThe note's serial number
data.promissoryNote.sequenceThe note's position in the schedule
data.promissoryNote.amountMinorThe note's amount, minor units as a string
data.promissoryNote.dueDateDue date, YYYY-MM-DD
data.promissoryNote.statusPAID, PROTESTED or CANCELLED
data.promissoryNote.occurredAtWhen the status occurred (ISO 8601)

The events carry no personal data. When you create a webhook subscription in the panel, these events are in the Senetle Ödeme (Promissory Notes) group. Delivery, signature verification and retry rules → Webhooks.

Refunds, cancellation and pre-authorization

  • Promissory-note payments cannot be refunded, fully or partially. Because the money did not pass through Lunixi, there is no amount to refund. If you do not want the buyer to be charged, cancel the open notes.
  • A collected (PAID) note cannot be cancelled. Repaying a collected amount is not done through Lunixi.
  • The payment itself is not voided; cancellation is per note.
  • Pre-authorization is not supported (see Enabling the method).

Errors

Error responses use the common error envelope; branch on code, not on message → Error Handling.

SituationResponseWhat to do
The schedule or block structure is broken (not a list, more than 24 rows, non-integer amount, wrong date format)400 VALIDATION_ERRORFix the field in details.errors[]
The schedule, note count or a debtor field breaks the rules400 payment.method.block_invalidFix the field in details.field; reasons below
The method is disabled in the panel422 payment.method.disabledEnable the method under Payments → Form Settings
No providerCode and none of the connected providers can take the payment422 payment.provider.none_eligibleCheck the results in details.candidates; you can choose the provider yourself with promissoryNote.providerCode
The provider is not connected or its connection settings cannot be read422 payment.provider.not_availableCheck the provider connection and settings in the panel
preauth: true was sent422 payment.preauth.unsupported_for_methodSend it without preauth
The provider rejected the debtor or the schedule400, payment FAILEDFix the details; use a new Idempotency-Key for a new attempt
The payment has no notes404 payment.promissory_note.not_foundCheck the paymentId
The note document cannot be fetched503 payment.promissory_note.document_unavailableRetry after a while
No permission to cancel403Cancel with a key or user that has the payment:void permission

Reasons for schedule and field errors

In a payment.method.block_invalid response the reason is in details.reason; every violation is listed in details.errors[] ({ "field", "reason" }).

details.reasonMeaning
requiredA required field, the schedule or noteCount was not sent
not_applicableThe field must not be sent in this case: its requiredWhen condition does not hold, or noteCount was sent alongside a schedule
invalid_typeWrong value type (e.g. noteCount is not a number, true sent to a text field)
invalid_formatFormat error: Turkish ID or tax number checksum, phone, e-mail, a date that does not exist, province code
invalid_optionValue outside the options; the note count is outside your connection-setting range or the amount is smaller than the note count; the address codes do not belong together
too_short, too_longLength limit exceeded (e.g. the street address is at most 250 characters)
too_few_items, too_many_itemsThe number of schedule rows is outside your connection-setting range, or the number of guarantors is outside minItems / maxItems
sum_mismatchThe schedule rows do not add up to amount
not_in_futureA due date is today or earlier
beyond_horizonA due date is more than 10 years from today
not_ascendingThe due dates are not in ascending order
not_allowed_for_formA schedule was sent in the Checkout Form call; on the form the schedule only comes from the intent
not_allowed_for_ + method codeA schedule was sent on an intent pinned to another method
unknown_fieldA field that is not in the provider's definition

Example field paths: promissoryNote.schedule[2].dueDate, promissoryNote.noteCount, promissoryNote.address.districtCode, promissoryNote.guarantors[1].identityNumber, promissoryNoteSchedule (your intent schedule when the form starts the payment).

Error codes

CodeHTTPMeaning and what to do
payment.promissory_note.not_found404There are no notes for this payment: it was not paid with promissory notes, the notes were not issued, or the payment belongs to another account. Check the paymentId
payment.promissory_note.document_unavailable503The note document cannot be fetched from the provider right now. Retry after a while

Next steps