BNPL Cancellation, Refund & Nurse Payout (Q1 & Q2)
See also the BNPL data model (../data-model/08-bnpl.md) and the business view (../business/09-installments-bnpl.md).
6. Q1 — Cancellation / refund of a BNPL booking mid-plan
Decisive rule: money ALWAYS flows customer ↔ SnappPay ↔ Balinyaar. Never refund the customer directly, and never route a nurse→customer refund. Balinyaar initiates the reversal through SnappPay's API using the stored payment token/transaction id:
- Full cancel/refund →
revert(full amount). - Partial / shortened-visit →
update(new amount must be strictly lower than the original settled amount) — orcancelper the provider's partial semantics.
SnappPay then, on its own ledger and asynchronously:
- cancels the customer's remaining UNPAID installments and credits their equivalent back to the customer's credit wallet (reusable BNPL credit — not merely "wiped"),
- refunds any already-PAID installment to the customer's bank account in ~7–10 business days.
The merchant's only role is to authorize/cancel; SnappPay owns the unwind. (VERIFIED verbatim: "اقساط پرداختنشده لغو و معادل آن به موجودی حساب اعتباری شما برگشت داده میشود"; "مبلغ قسط پرداختشده به حساب بانکی شما برگشت داده خواهد شد (۷ تا ۱۰ روز کاری)".)
Balinyaar's internal bookkeeping
- Record a
refundrow withrefund_channel = 'bnpl_revert',external_revert_reference,expected_customer_refund_eta, and arefund_statusthat staysprocessinguntil SnappPay confirms (a reconciliation job clears it). Surface the asynchronous 7–10-day window in the UI and reconciliation — never assume instant. - Decompose the refund across the two fee legs:
platform_fee_refunded_irrandnurse_payout_refunded_irr(the booking gross = platform fee + nurse payout; the refund must say how much of each is reversed). - Post balanced ledger entries (§3.2c/d): debit the decomposed
platform_revenue/nurse_payable, creditrefund_payable; record the revert reference on thebnpl_transactionsrow (reverted_amount_irr,reverted_at,refund_channel). - If the nurse has NOT been paid (booking still inside the dispute window / not in a processed batch): reverse the
nurse_payableaccrual — clean, nothing leaves Balinyaar. (This is the common case if you gate payout on the dispute window.) - If the nurse HAS been paid (refund-after-payout): take the clawback path — a
nurse_clawbacksrow + anurse_clawback_receivableledger leg (§3.2d), recovered from the next payout batch or written off.
Partial / shortened-visit maps to the update endpoint with a reduced amount: record refund_delta_irr, reduce settled_amount_irr on the bnpl_transactions row, and apply the same fee-leg decomposition.
UNCERTAIN (confirm at contracting): whether the provider returns its merchant commission on a full vs partial refund (full / pro-rata / not at all) is undocumented and directly affects platform P&L on cancellations. Model
provider_commission_reversed_amountas nullable and reconcile from the provider's refund response — do not hardcode. Digipay's exact mid-installment proration mechanics are likewise undocumented and contract-dependent.
7. Q2 — Under BNPL, who pays the nurse, and when?
Balinyaar pays the nurse, on Balinyaar's own normal weekly payout schedule, after EVV check-out and after the dispute window closes — exactly the same path as a card-funded booking. SnappPay never pays the nurse and is indifferent to Balinyaar's internal split. The customer's BNPL repayment timeline is completely decoupled from the nurse payout cycle.
The crucial accounting rule — the three-amount split
The nurse's payout is computed from the booking's own price and Balinyaar's own commission, NOT from the BNPL-net amount. SnappPay's commission is a cost of accepting BNPL, borne by Balinyaar, and must never be passed through to the nurse. Store three separate amounts so the two fee deductions are never conflated:
| Amount | Meaning | Drives |
|---|---|---|
gross_price_irr | What the customer is charged (booking price) | The invoice; the inbound escrow_held debit |
balinyaar_commission_irr | Balinyaar's own cut (was platform_fee_amount) | platform_revenue; the nurse payout |
bnpl_commission_irr | The BNPL provider's merchant discount | bnpl_fee_expense (platform expense) — never the nurse |
nurse_payout_amount = gross_price_irr − balinyaar_commission_irr
The nurse receives the identical amount whether the family paid by card or by SnappPay, and on the identical weekly timing (batch, gated on dispute_window_ends_at < now()). The only difference a BNPL order makes to the books is the extra bnpl_fee_expense leg that reduces Balinyaar's margin — not the nurse's pay.
Worked example (illustrative; rates are config): gross 5,000,000 IRR, Balinyaar commission 15% = 750,000, nurse payout = 4,250,000. If paid via SnappPay at a 10% merchant commission, bnpl_commission_irr = 500,000 is a Balinyaar expense; SnappPay settles 4,500,000 net to Balinyaar; the nurse still receives 4,250,000, and Balinyaar's net margin is 750,000 − 500,000 = 250,000 (before PSP/VAT). The nurse payout is invariant to the payment method.
↑ Back to topTiming guard (CONFIGURABLE): because BNPL settlement can lag, optionally key weekly-payout eligibility off
bnpl_transactions.settled_at(settlement actually received) in addition to EVV + dispute window, so the platform never advances a nurse before it holds the cash.