Skip to content

Demo: This is a demo template by Ruji Labs. The business, people, products, prices and reviews on this page are fictional and do not represent any real company.

zahin ooi
menu

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

seller payouts, from T+3

Client
Kedaiwira
Role
Product engineer, payments
Duration
3 months
Shipped
2023.10, v1.2
Stack
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

3 that shaped the design

  • 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

scroll sideways to see all of it

Delivered orders accrue into a seller balance. A cutoff job pays out what is safe to pay, and holds a small reserve.
transfersdeliveredorder eventsseller balanceaccrualreserve3% for 14 dayspayout run12:00 and 17:00name checkbefore first payoutbank railsinstant or batch

boxes are servicesdouble top rule is a storedashed is async or advisorygreen is what this project built

Code

excerpt, lightly trimmed

The payout run is one query. Anything it does not select simply waits for the next run.

payouts/select.sqlsql
-- 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

measured, not estimated

payout daywas T+3
T+0
bounced payoutswas 1.9%
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.

Demo only

This button is part of a demo template. Nothing was sent, booked or charged, and there is no real business behind this page.

Want a page like this for your business?

QR code: Darus Ishak, Ruji Labs contact cardScan or tap to get the contact card of Darus Ishak, Ruji Labs.Open contact card ↗