Payment Orchestrator
Subscription
Invoices

Invoices

Every billing period the subscription engine generates an invoice — the record of what is owed and what happened while collecting it. This page covers reading invoices, the two mutations (void, retry-charge), and the dunning machinery that retries failed charges before giving up.

All endpoints use your secret key as a Bearer token under https://api-gateway.lunixi.com/api/v1/subscriptions. List endpoints use cursor pagination (pageSize, pageToken).

⚠️

All invoice amounts are minor-unit (kuruş) integers — "amount": 149900 is ₺1.499,00.

Invoice lifecycle

Invoice collection flowFlow: an invoice is created at period start; auto-charge attempts collection, otherwise the invoice is sent to the customer. A failed charge enters the dunning retry cycle and, once retries are exhausted, the invoice is left uncollected.AUTO_CHARGESEND_INVOICESUCCESSPAIDFAILEDinvoice.createdCharge attemptCustomer paysinvoice.paidDUNNINGscheduled retriesLEGENDRETRY CYCLECOLLECTED
Dunning is not an error state but a scheduled collection programme: the invoice stays open until retries run out. When a retry succeeds, invoice.paid arrives late — your webhook consumer must treat it as a delayed success.

POST :id/void can take an open invoice out of the flow at any point (invoice.voided).

Status values

The status field on an invoice takes exactly these values:

statusMeaning
DRAFTNot finalized yet — no charge is triggered
OPENFinalized — collection is attempted
PAIDFully collected — terminal
UNCOLLECTIBLEMax dunning attempts exhausted — terminal
VOIDManually voided — terminal

The transitions are DRAFT → OPEN → PAID | UNCOLLECTIBLE | VOID; the three terminal statuses never change again.

List & retrieve

MethodPathWhat it does
GET/subscriptions/invoicesList invoices (cursor pagination)
GET/subscriptions/invoices/:idOne invoice with its line items and collection history
curl "https://api-gateway.lunixi.com/api/v1/subscriptions/invoices?pageSize=20" \
  -H "Authorization: Bearer at_live_5f3e2b1a..."
{
  "id": "inv_01JX9A2C6R",
  "subscriptionId": "sub_01JX5B8R3M",
  "status": "OPEN",
  "amount": 149900,
  "currency": "TRY",
  "periodStart": "2026-07-01T00:00:00Z",
  "periodEnd": "2026-08-01T00:00:00Z"
}

Void an invoice

POST /subscriptions/invoices/:id/void cancels an open invoice — no further collection attempts will be made for it. Use it for goodwill credits, billing mistakes, or when you settle a dispute out-of-band. Emits invoice.voided.

curl -X POST https://api-gateway.lunixi.com/api/v1/subscriptions/invoices/inv_01JX9A2C6R/void \
  -H "Authorization: Bearer at_live_5f3e2b1a..."

Retry a charge

POST /subscriptions/invoices/:id/retry-charge triggers an immediate collection attempt, outside the automatic dunning schedule. Typical use: the customer just updated their card (you received subscription.payment_card_swapped or card.added) and you want to collect right away instead of waiting for the next scheduled retry.

curl -X POST https://api-gateway.lunixi.com/api/v1/subscriptions/invoices/inv_01JX9A2C6R/retry-charge \
  -H "Authorization: Bearer at_live_5f3e2b1a..."

Dunning

When an AUTO_CHARGE collection fails, the invoice enters dunning: a schedule of automatic retries whose shape you define on the plan — see Plans:

Plan fieldRole in dunning
maxDunningAttemptsHow many automatic retries before giving up
dunningScheduleDaysWhen each retry runs, as day offsets from the first failure (e.g. [1, 3, 7])
gracePeriodDaysHow long the subscription keeps its entitlements while the invoice is unpaid

The flow, event by event:

invoice.payment_failed

The first charge (or a retry) failed. React here: e-mail the customer, show an in-app banner, point them at the customer portal to update their card.

Scheduled retries

The platform retries per dunningScheduleDays. Each failed retry emits another invoice.payment_failed; a successful one emits invoice.paid and dunning ends. A manual retry-charge also counts as an attempt to collect the same invoice.

invoice.uncollectible

All maxDunningAttempts are exhausted. The invoice is marked uncollectible — decide your policy: suspend access, keep the subscription in a degraded state, or write the amount off.

During gracePeriodDays the customer keeps access even though the invoice is unpaid — dunning is a recovery window, not an instant cut-off. Choose plan values that match how tolerant your product wants to be.

Payment method lost

If the stored card behind an AUTO_CHARGE subscription becomes unusable — deleted, or expired with no replacement — the platform emits subscription.payment_method_lost and switches the subscription's collection to MANUAL: invoices keep being issued, but nothing is auto-charged.

Recovery: the customer adds a new card (portal cards/update, or merchant API POST /subscriptions/cards + set-default), then you collect open invoices with retry-charge and, if desired, switch the subscription back to AUTO_CHARGE.

Errors

StatusMeaningWhat to do
401Missing/invalid Bearer keyCheck the Authorization header
404Invoice not foundVerify the id belongs to your account
409Invalid state (voiding a paid invoice, retry-charging a voided/paid one)Read GET /invoices/:id and act on the current state
422Retry not possible — e.g. no usable card on the subscriptionHave the customer add a card first, then retry

Webhooks

EventWhen
invoice.createdA period invoice was generated
invoice.paidCollection succeeded (auto, retry-charge or manual settlement)
invoice.payment_failedA charge attempt failed — dunning is running
invoice.uncollectibleDunning exhausted; the invoice will not be collected automatically
invoice.voidedThe invoice was voided
subscription.payment_method_lostStored card unusable — collection fell back to MANUAL

See Webhooks for delivery and signature verification.

Next steps

  • Plans — configure maxDunningAttempts, dunningScheduleDays, gracePeriodDays
  • Subscriptions — collection methods and lifecycle
  • Customer Portal — where customers fix their own failed payments