80 lines
11 KiB
HTML
80 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>7. Cancellation & Refunds — 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 & ground truths</a></li></ul></div><div class="group"><div class="label">Business requirements</div><ul><li><a href="index.html">Overview & MVP scope</a></li><li><a href="01-actors-and-onboarding.html">1. Actors & onboarding</a></li><li><a href="02-nurse-verification.html">2. Nurse verification</a></li><li><a href="03-service-catalog-and-pricing.html">3. Service catalog & pricing</a></li><li><a href="04-search-and-matching.html">4. Search & matching</a></li><li><a href="05-booking-and-scheduling.html">5. Booking & scheduling</a></li><li><a href="06-evv-and-service-delivery.html">6. EVV / service delivery</a></li><li><a class="active" href="07-cancellation-and-refunds.html">7. Cancellation & refunds</a></li><li><a href="08-payments-and-escrow.html">8. Payments & escrow</a></li><li><a href="09-installments-bnpl.html">9. Installments / BNPL</a></li><li><a href="10-payouts.html">10. Payouts to nurses</a></li><li><a href="11-reviews-trust-and-safety.html">11. Reviews, trust & safety</a></li><li><a href="12-messaging-and-emergencies.html">12. Messaging & emergencies</a></li><li><a href="13-tax-invoicing-and-legal.html">13. Tax, invoicing & legal</a></li><li><a href="14-notifications-and-admin.html">14. Notifications & admin</a></li></ul></div><div class="group"><div class="label">Database model</div><ul><li><a href="../data-model/index.html">Overview & 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 & 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 & pricing</a></li><li><a href="../data-model/04-verification-and-credentials.html">4. Verification & credentials</a></li><li><a href="../data-model/05-booking-and-scheduling.html">5. Booking & scheduling</a></li><li><a href="../data-model/06-payments-ledger-and-refunds.html">6. Payments, ledger & 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 & 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 & reference</a></li><li><a href="../data-model/13-partner-centers-and-future.html">13. Partner centers & future</a></li></ul></div><div class="group"><div class="label">Payments deep-dive</div><ul><li><a href="../payments/index.html">Overview & exec summary</a></li><li><a href="../payments/iranian-payment-reality.html">Iranian payment reality</a></li><li><a href="../payments/escrow-ledger.html">Escrow as a ledger</a></li><li><a href="../payments/bnpl-landscape.html">BNPL landscape & finding</a></li><li><a href="../payments/cancellation-and-payout.html">Cancellation & nurse payout</a></li><li><a href="../payments/integration-notes.html">Integration & schema touchpoints</a></li><li><a href="../payments/sources.html">Recommendations & sources</a></li></ul></div><div class="group"><div class="label">Research & strategy</div><ul><li><a href="../research/index.html">Overview & exec summary</a></li><li><a href="../research/market-and-competitors.html">Market & competitors</a></li><li><a href="../research/problems-and-risks.html">Problems & 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 & sources</a></li></ul></div><div class="group"><div class="label">Notes & 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>
|
|
<h1 id="7-cancellation-refunds">7. Cancellation & Refunds</h1>
|
|
<p><a href="index.html">← Business Requirements</a></p>
|
|
<h2 id="a-business-requirements">(a) Business requirements <a class="anchor" href="#a-business-requirements" aria-hidden="true">#</a></h2>
|
|
<ul>
|
|
<li>Cancellation/refund rules are <strong>tiered and structured</strong>, not a single blunt "default 100%". The platform defines <code>cancellation_policies</code> tiers by <strong>lead time</strong> and <strong>initiating actor</strong>:<ul>
|
|
<li><strong>Free</strong> cancellation more than 24h before start.</li>
|
|
<li><strong>Partial</strong> refund (e.g., 50%) under 24h.</li>
|
|
<li><strong>Customer no-show:</strong> up to 100% charge.</li>
|
|
<li><strong>Nurse no-show:</strong> full refund to the customer <strong>and</strong> a penalty/forfeiture for the nurse.</li>
|
|
</ul>
|
|
</li>
|
|
<li>The <strong>applicable policy is snapshotted onto the booking</strong> at booking time (mirroring the per-booking fee-rate snapshot), so later policy edits never rewrite history. The <strong>resolved</strong> cancellation fee / refund percentage is recorded on the refund event.</li>
|
|
<li>For multi-session engagements, <strong>cancellation is per remaining session:</strong> cancelling mid-engagement refunds only the un-started sessions, while completed-and-verified sessions remain payout-eligible.</li>
|
|
<li><strong>Refunds are admin-only</strong> — there is no customer self-service refund. A refund is initiated by an admin and <strong>must be linked to a support ticket</strong> (<code>tickets</code>) that holds the conversation and dispute evidence.</li>
|
|
<li>A refund <strong>decomposes across the two fee legs</strong> — how much of the platform commission and how much of the nurse payout is being reversed — because the booking gross is <code>platform commission + nurse payout</code>.</li>
|
|
</ul>
|
|
<h2 id="b-iran-specific-considerations">(b) Iran-specific considerations <a class="anchor" href="#b-iran-specific-considerations" aria-hidden="true">#</a></h2>
|
|
<ul>
|
|
<li>A flat percentage is too blunt for شبانهروزی live-in engagements and Iranian holiday-period bookings; tiered, snapshotted policy reduces dispute load.</li>
|
|
<li><strong>The refund money path depends on whether the nurse has already been paid</strong> (Section 8/10): pre-payout it is a clean reversal; post-payout it becomes a platform-funded refund plus a nurse clawback, because an Iranian bank transfer to a nurse's IBAN is effectively irreversible.</li>
|
|
<li>For BNPL bookings, the refund <strong>never</strong> goes nurse→customer or Balinyaar→customer directly — it is initiated through the BNPL provider's revert/cancel API (Section 8/9).</li>
|
|
</ul>
|
|
<h2 id="c-mvp-vs-deferred">(c) MVP vs DEFERRED <a class="anchor" href="#c-mvp-vs-deferred" aria-hidden="true">#</a></h2>
|
|
<ul>
|
|
<li><strong>MVP:</strong> tiered <code>cancellation_policies</code>; per-booking policy snapshot; admin-only, ticket-linked refunds; per-session cancellation for engagements; nurse-no-show vs customer-no-show handling; fee-leg decomposition on refunds.</li>
|
|
<li><strong>DEFERRED:</strong> automated nurse no-show penalty (manual admin action at launch); self-service partial-refund UI; holiday-specific cancellation overrides.</li>
|
|
</ul>
|
|
<h2 id="d-supporting-database-entities">(d) Supporting database entities <a class="anchor" href="#d-supporting-database-entities" aria-hidden="true">#</a></h2>
|
|
<p><strong><code>cancellation_policies</code></strong>, <code>bookings</code> (policy snapshot, <code>dispute_window_ends_at</code>), <code>refunds</code> (admin-only, <code>ticket_id</code>, fee-leg decomposition, <code>refund_channel</code>), <code>tickets</code>, <code>nurse_clawbacks</code> (post-payout case), <code>ledger_entries</code>.</p>
|
|
<h2 id="e-as-built-backend-phase-11">(e) As built (backend-phase-11) <a class="anchor" href="#e-as-built-backend-phase-11" aria-hidden="true">#</a></h2>
|
|
<p>Decisions fixed while building the refund/clawback/invoice engine (config-driven where possible):</p>
|
|
<ul>
|
|
<li><strong>Refund channel canonical code:</strong> the out-of-band bank refund is stored and served as <strong><code>manual</code></strong> (the wire</li>
|
|
</ul>
|
|
<p> code), not <code>manual_bank</code> — they are the same channel. Full set: <code>psp_card</code> | <code>bnpl_revert</code> | <code>manual</code>.</p>
|
|
<ul>
|
|
<li><strong>Ticket link is config-gated until b15.</strong> <code>refunds.ticket_id</code> is a nullable column with <strong>no FK yet</strong></li>
|
|
</ul>
|
|
<p> (<code>tickets</code> arrives in b15). "A refund must link a ticket" is enforced by the <code>refund_ticket_required</code> config flag, <strong>default <code>false</code></strong> so admin refunds are testable today; b15 wires the FK and flips it on.</p>
|
|
<ul>
|
|
<li><strong>BNPL refund ETA</strong> is <code>now + config(bnpl_refund_eta_business_days, default 10)</code> business days (Fridays skipped),</li>
|
|
</ul>
|
|
<p> surfaced as <code>expected_customer_refund_eta</code>; the refund sits in <code>processing</code> until reconciled. Card refunds are immediate (<code>succeeded</code>, no ETA). Card and BNPL post the <strong>same</strong> reversal ledger legs.</p>
|
|
<ul>
|
|
<li><strong>Pre-payout vs post-payout fork</strong> is decided by whether the nurse was already paid — derived from the booking's</li>
|
|
</ul>
|
|
<p> <code>dispute_window_ends_at</code> close until b13 ships <code>nurse_payouts</code> (a <code>refund_assume_nurse_paid</code> override exists). Clawback <strong>recovery/netting is b13</strong>; b11 only opens the <code>pending</code> receivable + supports admin write-off.</p>
|
|
<blockquote><p><strong>Related:</strong> Data model — <a href="../data-model/06-payments-ledger-and-refunds.html">Payments Ledger & Refunds</a>.</p>
|
|
</blockquote>
|
|
<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>
|