Same-day payouts for Kedaiwira
Sellers used to wait three days for their money. Now they are paid before 6 pm on the day the order is delivered. Kedaiwira: online marketplace for 26,000 small Malaysian sellers.
T+0
- Kedaiwira
- Product engineer, payments
- 3 months
- 2023.10, v1.2
- Python, Django, PostgreSQL, Celery
Problem
For a small seller, three days of float is the difference between restocking this week or next. Kedaiwira paid out in one nightly batch, three working days after delivery, and 1.9% of payouts bounced back because of closed accounts or name mismatches.
Each bounce was fixed by email, and the seller was not paid until someone in operations noticed.
Constraints
- Instant transfer rails have per-transaction fees, so batching still matters for very small amounts.
- Bank account names must be verified before the first payout, without asking sellers for documents again.
- Refunds and disputes can arrive after a payout has gone out.
Architecture
Code
The payout run is one query. Anything it does not select simply waits for the next run.
-- Sellers eligible for this run, amounts in senSELECT s.id, b.available_sen - b.reserve_sen AS payable_senFROM sellers sJOIN seller_balances b ON b.seller_id = s.idWHERE s.bank_name_verified AND NOT s.payouts_paused AND b.available_sen - b.reserve_sen >= 1000 -- RM 10 minimumFOR UPDATE OF b SKIP LOCKED;
Result
- payout day
- T+0
- bounced payouts
- 0.2%
- paid out on the launch week
- RM 4.1m
- seller retention after 6 months
- +8%
Operations retired the payout spreadsheet the following month. The two daily runs are still the only scheduled jobs that touch money.