Files
baya-monorepo/product/data-model/08-bnpl.md
T
2026-06-24 01:32:46 +03:30

2.8 KiB

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.

Field Type Notes
id BIGINT PK
payment_transaction_id BIGINT FK UNIQUE 1:1
provider_code NVARCHAR(50) snapppay / digipay / tara / torobpay
merchant_of_record NVARCHAR(40) Balinyaar entity or partner center
external_payment_token NVARCHAR(200) For verify/settle/revert
external_transaction_id NVARCHAR(200)
eligibility_status NVARCHAR(30)
order_amount_irr BIGINT Gross order
settled_amount_irr BIGINT Net of provider commission actually received
bnpl_commission_irr BIGINT Provider's merchant discount = platform expense (never the nurse's)
currency NVARCHAR(5) IRR/TOMAN at boundary; convert in
installment_count TINYINT Informational (default 4) — owned by the provider
status NVARCHAR(30) State machine: eligible/token_issued/verified/settled/reverted/cancelled/failed
settled_at DATETIME2 NULL Per-transaction — timing is contract-defined (daily/T+1-3/weekly), never assumed instant
revert_transaction_id, reverted_amount_irr, reverted_at Reversal path
refund_channel NVARCHAR(20)
callback_payload_json NVARCHAR(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.