Payout validation map
This document turns discussion outcomes into concrete validation points. It focuses on prevention, operator clarity, and auditability. “Settlement” concerns from the source note are translated here into payout checks that fit current wallet and payout semantics.
Validation objectives
- Prevent wrong payout amount before reservation.
- Separate internal payout identity from external bank reference.
- Make policy-driven adjustment handling explicit and reviewable.
- Preserve execution history per attempt while keeping payout root searchable.
- Ensure reversal records obligation instead of inventing wallet liquidity.
Core new entities / fields
-
payouts.payout_number: generated at initiation withJPO.... -
payout_executions.external_reference_id: immutable attempt-level bank/provider ref. -
payouts.reference_id: latest/final external reference cache. -
payout_adjustments: durable obligations and offsets.
Decision tree
Scroll horizontally on small screens. Green-tinted nodes: policy or decision; amber: reject / exception paths. Pills on lines name the branch taken on that connector.
Validation matrix
| Stage | Validation | Reason | Outcome |
|---|---|---|---|
| Initiation | Wallet active, payout account active, currency match, no active payout conflict | Prevent duplicate or invalid payout setup | Reject before reservation |
| Initiation | Server computes adjustments under product policy with vendor fallback | Commercial logic cannot depend on operator memory | Applied set or exception path |
| Initiation | Selected manual adjustments must be eligible for this scope and unresolved | Prevent stale or cross-scope deductions | Reject or require exception approval |
| Approval | Normal OTP flow only after any exception approval resolved | Separate policy override approval from payout approval | Gate outbound cash |
| Execution | External reference required here, not at initiation | Real bank/provider refs only known after transfer | Persist per execution attempt and cache on payout root |
| Execution | PoP file required | Audit + vendor communication trail | Reject incomplete execution |
| Post-execution evidence | If the wrong proof of payment was uploaded, use a dedicated proof replacement endpoint with a new file and a reason note | A correct payout should not need a full reversal just to fix the evidence file | Replace the active proof link while preserving the old document in audit history |
| Execution | If amount mismatch, mismatch note required | Compensation path must be explainable |
awaiting_reconciliation queue state
|
| Reversal | Only finance reconciliation approver or system admin may reverse executed payout | High-risk action after money already left platform | Restrict endpoint |
| Reversal | Always create adjustment unless recovery already happened explicitly | Obligation must remain visible and trackable | Durable recoverable/payable record |
Adjustment class defaults
| Class | Default mode | Notes |
|---|---|---|
| Carry-forward deduction | Often auto-apply | Oldest-first reasonable default |
| Carry-forward credit | Often auto-apply | Restores prior underpayment on next payout |
| Gross payout invoice fees | Usually manual / non-deducting | Track as invoice-backed obligation instead of shrinking transfer |
| Manual cash recovery | Manual only | Requires supporting evidence |
Doc rules
- Carry-forward adjustments: structured reason/note, file optional.
- Gross invoice path: invoice reference plus optional/required document policy.
- Manual recovery: supporting document required.
- Execution: PoP required on every successful execution.
- Proof replacement: the system should keep both the original proof and the replacement proof in history.
- Wrong-beneficiary/compliance reversal: evidence required by validation rules.
Why store external reference twice?
Attempt-level storage keeps execution history correct. Root-level cache keeps payout search, reports, and operator lookup simple.
Additional endpoint to add
The payout API also needs a dedicated endpoint for replacing the proof of payment document after execution when the transfer amount was correct but the attached document was wrong.
| Endpoint | Purpose | Rules |
|---|---|---|
POST /payouts/:id/proof-of-payment/replace
|
Replace the active proof document for an already executed payout without changing the payout amount | Require replacement file, reason note, strict authorization, and full audit preservation of the earlier file |