Track 04 finance control · working test-mode prototype

One item comes back.Reverse the exact transfer.

Working demo64 / 64 control fixtures₹0 wrong-seller allocationDeterministic test provider
The control surface

One seeded claim, five illustrated steps.

Each seeded scenario is presented on the same reviewable surface - evidence, split, reversal, approval, reconciliation. Here is demo claim RET-260903-031, start to close.

RET-260903-031Simulation · reversal before refund · replayable
Refund₹2,328.54Seller reversal₹1,979.26Platform share₹349.28
For partial refunds on a payment transferred to multiple accounts, Razorpay cannot determine which transfer to reverse partially. You will have to use the transfer reversal API.
Razorpay Route - official documentation.razorpay.com/docs/payments/route/refunds
The control loop

Evidence in. Balanced plan out. Each demo step recorded.

After a return is approved, the prototype runs a reviewable state machine. It records intent before provider calls, pauses unknown outcomes for reconciliation, and waits for confirmed reversals before refunding.

1
Assess
needs_review

Precomputed returned-line and policy fixtures are treated as untrusted, validated against the seeded order, then passed to deterministic paise calculation.

2
Approve
ready_for_approval

A named operator approves the frozen plan, bound to an exact fingerprint. Separate maker-checker roles and RBAC remain production work.

3
Execute
processing

Pre-flight re-fetch fails closed on drift. Intent and a stable receipt are recorded so unknown Route outcomes pause for reconciliation, not a blind retry.

4
Settle
completed

The customer refund starts only after required reversals confirm; the simulator or configured Test Mode status is then recorded.

needs_review → evidence requested blocked → manual intervention reversal_result_unknown → receipt-based reconcile
What you get

The missing brain between a return and your payout ledger.

01

Exact-paise allocation

Every rupee computed in integer paise with largest-remainder rounding - no floats, no drift. The split sums to the refund, to the last paisa, or it never runs.

Aavya Textiles · reverse−₹1,979.26
Marketplace · contribute−₹349.28
Shipping · non-refundable₹0.00
Customer refund₹2,328.54
02

Shortfall handling

When the reversible transfer balance is too low, the demo blocks approval, shows the residual, and can open an owned payments-reconciliation case instead of moving partial money.

RET-260903-038 · AnayaApproval blocked

Needs ₹850.85 · only ₹49.15 reversible → approval blocked, reconciliation required.

03

Fail-closed retry safety

A timed-out reversal becomes unknown, never a blind retry. The prototype fetches by stable receipt; durable cross-process protection remains production work.

reversal_result_unknown → reconcile
04

Process-local audit history

Plan frozenKhushi Diwan · 08:57
Demo transfer reversedmasked simulator reference
Demo refund completedsimulator status recorded
05

Exposure forecasting

A dated TimesFM 2.5 backtest measured aggregate refund exposure on 56 synthetic daily totals. It is illustrative planning evidence, not production accuracy.

3.77%7-day WAPE
3.43%14-day
3.71%30-day
06

Cross-rail roadmap

The prototype implements Razorpay Route simulation and an optional Test Mode adapter. Stripe Connect and Cashfree are roadmap research; no adapters are included.

PROPOSED ROADMAP · NOT IMPLEMENTED
Assurance

Boring where it counts. Provable where it matters.

The prototype calculates the money plan without holding or pooling funds. Its default provider is a deterministic simulator; an optional Razorpay Test Mode adapter is available, and live keys are rejected.

returnsplit-engine · deterministic control set · 64 recordsPASS
fixture assertions0 / 64
unsafe automations0
wrong-seller overage₹0
expected exceptions surfaced0 / 16
Engine contract

Plan first. Execute after approval.

The workbench posts the reviewed fingerprint to its same-origin preflight route before approval, then enforces reversal-before-refund ordering. Demo state is process-local.

conceptual-flow.ts
const claimId = "RET-260903-031";const endpoint = `/api/claims/${claimId}/preflight`; // Re-fetch provider state before approvalconst check = await fetch(endpoint, {  method: "POST",  body: JSON.stringify({ expectedPlanFingerprint }),}); if (!check.ok) return "fail_closed";// Approval uses the same reviewed fingerprint// and executes through the server-side saga.
FAQ

Questions? Answered.

Start with the golden claim, then inspect the evaluation snapshot.

No. The default provider is a deterministic simulator, and the optional adapter accepts Razorpay Test Mode credentials only. ReturnSplit never pools or custodies funds; live keys are rejected.

For a partial refund on a payment split across multiple Route transfers, Razorpay cannot decide which transfer to reverse - its own docs say so. This prototype computes the per-seller paise and demonstrates reversal-before-refund ordering in a resumable, process-local saga. Durable crash recovery remains production work.

The demo blocks approval when the reversible balance is insufficient (claim RET-260903-038 has only ₹49.15 available), exposes the residual, and can open an owned payments-reconciliation case. It does not silently continue or write off the gap.

Amounts are computed in integer paise with largest-remainder rounding. Across 64 pre-structured synthetic records, the engine matched all expected finance-control decisions with ₹0 wrong-seller overage and 0 unsafe automations. That is fixture agreement, not extraction accuracy or live-provider evidence.

The workbench records process-local approval, execution, and operations history and can generate a redacted audit export. It is not durable, signed, hash-chained, WORM-retained, or a compliance record; production needs an authenticated, tenant-scoped, tamper-evident store.

Open the workbench and replay seeded partial-refund scenarios through the deterministic split, human approval, simulated execution, and audit export. The fixtures are synthetic and do not ingest a live merchant return.

See exactly which transfer to reverse.

Open the workbench and replay a seeded partial-refund scenario - the per-seller split, approval gate, simulated execution, and process-local audit history.