Money, tax and commission rules
This page states what the code does today. Where a rule is a placeholder or not built, it says so. No rule here is a recommendation; business rules are decided by the owner and recorded in docs/handoff.md.
Currency and amounts
- Platform currency: Qatari riyal (QAR) by default. Supported codes: QAR, EGP, SAR, AED, USD, EUR, GBP.
- Amounts are integers in the currency's minor unit (dirham for QAR), never floating point; in the API they travel as strings. Rates and percentages are integer basis points (100 bp = 1%).
- Exchange rates exist for display only. Nothing is charged in a converted currency.
Tax
- Tax rates are configured by country (optionally state and postcode) with validity dates, an inclusive/exclusive flag and whether shipping is taxed. The most specific matching rate wins; tax is rounded per line.
- With inclusive pricing the buyer pays exactly the price shown and the tax is the part of it that is tax.
- Qatar: 0%, prices tax-inclusive, shipping taxable (confirmed by the owner). Egypt: seeded at 14% VAT, inclusive, shipping taxable.
- A product without a tax class cannot be checked out.
Shipping fees
- Shipping is quoted per seller shipment, by delivery zone and method. Rate types: flat, weight-based, price-based and free, with optional bands, per-category rates and a free-shipping threshold.
- Qatar configuration: one nationwide zone, Standard 25.00 QAR and Express 50.00 QAR.
- There is no free-shipping threshold configured today (one was considered and removed). Coupons can grant free shipping.
Commission
- Every seller has a commission plan: a default rate in basis points, optional per-category rules (the most specific category wins) with per-line minimum and maximum fees, and an optional fixed fee. Plans are managed by super admins; rates are capped at 50%.
- The seeded plan is 8.5%.
- Commission is calculated on the seller's goods value — before tax and shipping, and before any discount the platform funds — and is fixed when checkout is confirmed.
- A seller without a plan cannot sell.
The ledger
Every financial event writes one double-entry ledger transaction whose entries sum to zero. Seller balances, platform revenue and driver cash are derived from the entries; a job reconciles them hourly. Replaying a payment notification cannot post twice.
When an order counts as "paid"
Payment is captured as soon as it is authorised, which moves the order to PAID. For cash on delivery, PAID means the cash obligation has been recorded against the delivery — not that cash is in hand. The cash is tracked as cash in transit until the driver hands it in.
Payment methods
| Method | What the code does |
|---|---|
| Cash on delivery | Live. Refused for digital goods, outside enabled countries (default Qatar and Egypt) and above a maximum order value (default 20,000.00). |
| Stripe card | Real integration, platform is merchant of record, no split payments. Supports USD, EUR, GBP, EGP, SAR and AED — not QAR — and needs a secret key to run. |
| Paymob | Not implemented; the adapter refuses every payment. |
| Sandbox card | Development only; refused in production. |
| Gift cards, loyalty points | Applied after tax, gift cards first, then points. |
Seller payouts
| Rule | Value |
|---|---|
| Hold period | 7 days from when the earning is posted |
| Minimum payout | 100.00 (10,000 minor units) |
| Extra approval | Payouts above 50,000.00 need a person to approve |
| Bank account | Must be verified |
| Trigger | Manual: finance starts a payout run. No automatic schedule. |
| Transfer | Manual: finance sends the bank transfer outside the system, then marks the payout paid. |
Payout statuses: scheduled → pending approval → approved → processing → paid, failed or cancelled. A settlement statement is produced when a payout is paid.
Cash on delivery settlement
The driver records the cash at the door; when it is handed in, a dispatcher records the settlement and the ledger clears it from cash in transit. Shortfalls are recorded and flagged to finance, not rejected. A driver with a cash limit of 0 receives no cash tasks.
Refunds
- Amount: what the buyer paid for the returned units (discounted price plus tax) plus a proportional share of shipping.
- Who bears it: the seller bears the refund and the matching commission is returned to the seller.
- How it is paid back: in proportion to how the order was paid (card, gift card, points). Card refunds go back through the provider. COD refunds are recorded as owed and paid by manual bank transfer.
- Cancellation: free for the buyer until a seller accepts. Before capture the payment is voided; after capture it is refunded.
- Return window: 14 days from delivery. A refund needs the goods received first unless explicitly waived.
- Return postage: seller pays when the reason is the seller's fault; otherwise the buyer.
- Disputes are resolved by an admin, for the buyer or the seller, optionally with a refund amount.
Coupons, gift cards and loyalty
- Coupons (implemented): percentage, fixed amount, free shipping and buy-X-get-Y, with stacking and usage limits; funded by the platform, the seller, or shared 50/50.
- Gift cards (implemented): issued by admins with a reason (sold or goodwill) and redeemed at checkout. Buyers cannot buy gift cards on the site yet.
- Loyalty points (implemented, placeholder values): 1 point per 100 minor units paid, earned when the order is paid; 1 point = 1 minor unit; points can pay at most 50% of an order.
- Seller opt-in campaigns are modelled in the database but not implemented.
- Card payments in QAR (Stripe does not accept QAR here; Paymob not built).
- Scheduled payout runs and automated bank transfers.
- Automated refund payouts for COD orders.
- Driver pay rates and loyalty values (placeholders until a settings module exists).
- Offsetting a driver's cash on hand against what the driver is owed.
- Charging in a currency other than the price currency.
- Holding sellers' funds as merchant of record is flagged as a licensing and tax question for counsel in Qatar and Egypt.