clean and refine product docs structure

This commit is contained in:
hamid
2026-06-24 01:32:46 +03:30
parent be07c703ec
commit 1df3cd9f64
113 changed files with 6078 additions and 4973 deletions
+69
View File
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Escrow as an Internal Ledger, Not Held Cash — Balinyaar docs</title>
<link rel="stylesheet" href="../assets/doc.css">
</head>
<body>
<div class="layout">
<aside class="sidebar">
<a class="brand" href="../index.html"><span class="dot"></span> Balinyaar docs</a>
<p class="tagline">Trust-first home-nursing marketplace · Iran</p>
<nav><div class="group"><div class="label">Start here</div><ul><li><a href="../index.html">Docs home</a></li><li><a href="../overview/platform-summary.html">Platform summary &amp; ground truths</a></li></ul></div><div class="group"><div class="label">Business requirements</div><ul><li><a href="../business/index.html">Overview &amp; MVP scope</a></li><li><a href="../business/01-actors-and-onboarding.html">1. Actors &amp; onboarding</a></li><li><a href="../business/02-nurse-verification.html">2. Nurse verification</a></li><li><a href="../business/03-service-catalog-and-pricing.html">3. Service catalog &amp; pricing</a></li><li><a href="../business/04-search-and-matching.html">4. Search &amp; matching</a></li><li><a href="../business/05-booking-and-scheduling.html">5. Booking &amp; scheduling</a></li><li><a href="../business/06-evv-and-service-delivery.html">6. EVV / service delivery</a></li><li><a href="../business/07-cancellation-and-refunds.html">7. Cancellation &amp; refunds</a></li><li><a href="../business/08-payments-and-escrow.html">8. Payments &amp; escrow</a></li><li><a href="../business/09-installments-bnpl.html">9. Installments / BNPL</a></li><li><a href="../business/10-payouts.html">10. Payouts to nurses</a></li><li><a href="../business/11-reviews-trust-and-safety.html">11. Reviews, trust &amp; safety</a></li><li><a href="../business/12-messaging-and-emergencies.html">12. Messaging &amp; emergencies</a></li><li><a href="../business/13-tax-invoicing-and-legal.html">13. Tax, invoicing &amp; legal</a></li><li><a href="../business/14-notifications-and-admin.html">14. Notifications &amp; admin</a></li></ul></div><div class="group"><div class="label">Database model</div><ul><li><a href="../data-model/index.html">Overview &amp; decisions</a></li><li><a href="../data-model/diagrams.html">Diagrams</a></li><li><a href="../data-model/01-identity-and-access.html">1. Identity &amp; access</a></li><li><a href="../data-model/02-geography.html">2. Geography</a></li><li><a href="../data-model/03-services-and-pricing.html">3. Services &amp; pricing</a></li><li><a href="../data-model/04-verification-and-credentials.html">4. Verification &amp; credentials</a></li><li><a href="../data-model/05-booking-and-scheduling.html">5. Booking &amp; scheduling</a></li><li><a href="../data-model/06-payments-ledger-and-refunds.html">6. Payments, ledger &amp; refunds</a></li><li><a href="../data-model/07-payouts.html">7. Payouts</a></li><li><a href="../data-model/08-bnpl.html">8. BNPL / installments</a></li><li><a href="../data-model/09-messaging.html">9. Messaging</a></li><li><a href="../data-model/10-reviews-and-records.html">10. Reviews &amp; records</a></li><li><a href="../data-model/11-notifications.html">11. Notifications</a></li><li><a href="../data-model/12-audit-config-and-reference.html">12. Audit, config &amp; reference</a></li><li><a href="../data-model/13-partner-centers-and-future.html">13. Partner centers &amp; future</a></li></ul></div><div class="group"><div class="label">Payments deep-dive</div><ul><li><a href="index.html">Overview &amp; exec summary</a></li><li><a href="iranian-payment-reality.html">Iranian payment reality</a></li><li><a class="active" href="escrow-ledger.html">Escrow as a ledger</a></li><li><a href="bnpl-landscape.html">BNPL landscape &amp; finding</a></li><li><a href="cancellation-and-payout.html">Cancellation &amp; nurse payout</a></li><li><a href="integration-notes.html">Integration &amp; schema touchpoints</a></li><li><a href="sources.html">Recommendations &amp; sources</a></li></ul></div><div class="group"><div class="label">Research &amp; strategy</div><ul><li><a href="../research/index.html">Overview &amp; exec summary</a></li><li><a href="../research/market-and-competitors.html">Market &amp; competitors</a></li><li><a href="../research/problems-and-risks.html">Problems &amp; risks</a></li><li><a href="../research/verification.html">Verification (research)</a></li><li><a href="../research/legal-landscape.html">Legal landscape</a></li><li><a href="../research/go-to-market.html">Go-to-market &amp; sources</a></li></ul></div><div class="group"><div class="label">Notes &amp; more</div><ul><li><a href="../notes/open-questions.html">Open questions</a></li><li><a href="../notes/future-ideas.html">Future ideas</a></li><li><a href="../wireframes/index.html">Wireframes</a></li><li><a href="../fa/index.html">Farsi documents</a></li></ul></div></nav>
</aside>
<main class="main"><div class="content">
<div class="topbar"><button class="theme-toggle" type="button" onclick="__t()">theme</button></div>
<p><a href="index.html">← Payments overview</a></p>
<h1 id="escrow-as-an-internal-ledger-not-held-cash">Escrow as an Internal Ledger, Not Held Cash</h1>
<p>Because Balinyaar cannot custody buyer funds (§2.2), <strong>"escrow" must be a software construct: a double-entry ledger STATE over money that legally sits at a licensed provider/bank.</strong> The original ~45-table model had <strong>no ledger</strong> — escrow was only inferable by joining <code>bookings.status</code>, <code>bookings.payout_released</code>, <code>payment_transactions.status</code>, and <code>refunds</code>, with no single answer to "how much do we owe nurses right now?" Three independent critiques rated this a <strong>critical</strong> gap. The fix is one append-only table.</p>
<p>The ledger entity is detailed in the data model: see <a href="../data-model/06-payments-ledger-and-refunds.html">payments, ledger &amp; refunds</a>.</p>
<h2 id="31-ledger_entries-the-financial-source-of-truth">3.1 <code>ledger_entries</code> — the financial source of truth <a class="anchor" href="#31-ledger_entries-the-financial-source-of-truth" aria-hidden="true">#</a></h2>
<p>Append-only, never updated or deleted. Every money event posts <strong>balanced</strong> rows sharing a <code>transaction_group_id</code> (Σ debit = Σ credit). Per-nurse balances are <em>derived by filter</em>, never cached in a drifting wallet-balance column.</p>
<p><strong>Account types:</strong></p>
<div class="table-wrap"><table><thead><tr><th>account_type</th><th>Meaning</th></tr></thead><tbody>
<tr><td><code>escrow_held</code></td><td>Funds received and held (over provider custody) not yet released or refunded</td></tr>
<tr><td><code>platform_revenue</code></td><td>Balinyaar's own commission income</td></tr>
<tr><td><code>nurse_payable</code></td><td>What the platform owes the nurse (accrued, awaiting weekly payout)</td></tr>
<tr><td><code>refund_payable</code></td><td>Amount owed back to the customer / in-flight reversal</td></tr>
<tr><td><code>bnpl_fee_expense</code></td><td>The BNPL provider's merchant commission — a platform expense</td></tr>
<tr><td><code>nurse_clawback_receivable</code></td><td>Money a nurse owes back after a refund-after-payout</td></tr>
</tbody></table></div>
<h2 id="32-the-postings">3.2 The postings <a class="anchor" href="#32-the-postings" aria-hidden="true">#</a></h2>
<p>Amounts are positive; <code>direction</code> carries the sign. The three-amount split (<code>gross_price_irr</code>, <code>balinyaar_commission_irr</code>, <code>bnpl_commission_irr</code>) is defined in §7.</p>
<p><strong>(a) Card payment capture (inbound):</strong></p>
<pre><code>DEBIT escrow_held gross_price_irr
CREDIT platform_revenue balinyaar_commission_irr
CREDIT nurse_payable nurse_payout_amount (= gross balinyaar_commission)</code></pre>
<p><strong>(b) BNPL settle (inbound) — identical to a card capture, plus the provider-fee leg:</strong></p>
<pre><code>DEBIT escrow_held gross_price_irr
CREDIT platform_revenue balinyaar_commission_irr
CREDIT nurse_payable nurse_payout_amount
DEBIT bnpl_fee_expense bnpl_commission_irr
CREDIT escrow_held bnpl_commission_irr (escrow reflects NET cash actually received)</code></pre>
<p>Posted <strong>once</strong>, idempotently, keyed on the settling transaction. <strong>No installment-level postings</strong> — the customer's repayment schedule is SnappPay's ledger, not ours.</p>
<p><strong>(c) Refund — BEFORE the nurse is paid out (clean reversal):</strong></p>
<pre><code>DEBIT platform_revenue platform_fee_refunded_irr
DEBIT nurse_payable nurse_payout_refunded_irr
CREDIT refund_payable (sum)</code></pre>
<p>Clear <code>refund_payable</code> when the PSP / SnappPay confirms the customer cash-back. Nothing leaves Balinyaar toward the nurse — the <code>nurse_payable</code> accrual is simply reversed.</p>
<p><strong>(d) Clawback — refund AFTER the nurse was already paid:</strong> The nurse's <code>nurse_payable</code> was already drained by a processed payout batch, so there is nothing left to reverse. Instead the platform books a receivable:</p>
<pre><code>DEBIT nurse_clawback_receivable amount_irr (nurse_id set; nurse now owes the platform)
CREDIT refund_payable amount_irr</code></pre>
<p>Recovered by <strong>netting against the nurse's next <code>nurse_payable</code></strong> at batch time, or marked <code>written_off</code> if uncollectable. A <code>nurse_clawbacks</code> row carries the lifecycle (<code>pending</code> / <code>recovered</code> / <code>written_off</code>). This is unavoidable because <strong>Iranian payouts are real bank transfers — hard/impossible to reverse</strong> — so the right defense is <em>gating payout on the dispute window</em>, with clawback as the fallback.</p>
<h2 id="33-why-the-ledger-not-more-columns">3.3 Why the ledger, not more columns <a class="anchor" href="#33-why-the-ledger-not-more-columns" aria-hidden="true">#</a></h2>
<p>A marketplace that holds escrow, pays out weekly minus commission, and handles refunds + clawbacks has exactly the shape double-entry was invented for. The MVP cost is <strong>one table + posting discipline</strong>. The alternative (more money columns on bookings/payouts) cannot answer "how much is held but unreleased" without fragile joins and makes bank/Shaparak reconciliation nearly impossible. Keep the per-booking fee snapshot as the <em>pricing</em> record; the ledger is the <em>financial-truth / reconciliation</em> layer posted alongside.</p>
<a class="back-to-top" href="#">↑ Back to top</a>
</div></main>
</div>
<script>
(function(){var k='balinyaar-docs-theme';var s=localStorage.getItem(k);
if(s)document.documentElement.setAttribute('data-theme',s);
else if(matchMedia('(prefers-color-scheme: dark)').matches)document.documentElement.setAttribute('data-theme','dark');})();
function __t(){var d=document.documentElement;var n=d.getAttribute('data-theme')==='dark'?'light':'dark';
d.setAttribute('data-theme',n);localStorage.setItem('balinyaar-docs-theme',n);}
</script>
</body>
</html>