Domain 8 — BNPL / Installments

← Database Model

Related: business requirements — Installments / BNPL. Settlement and reversal detail are explained in depth in the payments docs — BNPL landscape and Cancellation & payout.

Resolved. Because verified research shows Iranian provider-financed BNPL settles the full amount to the merchant in one lump (provider owns the customer's installments and default risk), a BNPL order is — in our books — a card payment that lands net-of-fee. The original installment_plans + installment_entries subsystem (which tried to track the customer's repayment schedule and default) is deleted: it modeled a receivable Balinyaar never owns and a risk it never bears.

bnpl_transactions [MVP] — NEW (replaces installment_plans)

Role: One row per BNPL order, 1:1 with its payment_transaction — the single inbound settlement to reconcile, plus the revert path. Why one row, not a plan+entries tree: there is nothing to amortize on our side; we track the settlement, the provider's commission, and the reversal.

FieldTypeNotes
idBIGINT PK
payment_transaction_idBIGINT FK UNIQUE1:1
provider_codeNVARCHAR(50)snapppay / digipay / tara / torobpay
merchant_of_recordNVARCHAR(40)Balinyaar entity or partner center
external_payment_tokenNVARCHAR(200)For verify/settle/revert
external_transaction_idNVARCHAR(200)
eligibility_statusNVARCHAR(30)
order_amount_irrBIGINTGross order
settled_amount_irrBIGINTNet of provider commission actually received
bnpl_commission_irrBIGINTProvider's merchant discount = platform expense (never the nurse's)
currencyNVARCHAR(5)IRR/TOMAN at boundary; convert in
installment_countTINYINTInformational (default 4) — owned by the provider
statusNVARCHAR(30)State machine: eligible/token_issued/verified/settled/reverted/cancelled/failed
settled_atDATETIME2 NULLPer-transaction — timing is contract-defined (daily/T+1-3/weekly), never assumed instant
revert_transaction_id, reverted_amount_irr, reverted_atReversal path
refund_channelNVARCHAR(20)
callback_payload_jsonNVARCHAR(MAX)Raw verify/settle payload
timestamps

Relations: 1:1 → payment_transactions. State-machine guard on status for idempotency.

bnpl_settlement_entries [DEFERRED]

Role/Why: Only needed if a future provider uses tranched settlement (pays the platform over time). No mainstream Iranian provider does today, so it's modeled-but-inactive; adding it later is a purely additive migration.

↑ Back to top