Paystack and Mobile Money integration
Payment bugs are not like other bugs. A broken layout embarrasses you; a double charge costs a customer real money and costs you the relationship. Yet payment integration is where most projects cut corners, because the happy path is easy to demo and the failure paths are invisible until they happen.
The failure paths are the job. Gateways retry webhooks. Networks drop mid-confirmation. Users press pay twice. A payment integration is correct only when every one of those produces exactly one charge, and the system can prove it afterwards.
What that includes
Paystack and Mobile Money
Card, bank and MoMo collection, initialised server side so the amount is never decided by the browser.
Idempotent webhooks
Handlers keyed on the provider reference inside a transaction, so a replayed or duplicated event is a no-op rather than a second charge.
Integer money
Balances held as whole pesewas with database-level constraints, because floating point arithmetic loses money quietly.
Settlement and payouts
Commission splits, vendor settlement runs and payout state machines, with the rate stamped on each transaction so changing it never rewrites history.
Where I have done this
- AkyedieA gift card platform where the money math is provably correct.Fintech, gift cards
- Spice N CookMobile-first ordering with one authoritative pricing engine.Restaurant ordering
- Beihge HairBookings, live stock and class registration on shared hosting.Beauty and retail
- Grow With A.N.Server-rendered marketing with payments behind it.Coaching
Common questions
- How do I accept Mobile Money payments on my website?
- Through a gateway such as Paystack, which covers MTN, Telecel and AirtelTigo alongside cards. Your server initialises the transaction, the customer authorises it, and a webhook confirms it. The confirmation must be verified server side against the provider signature, never trusted from the browser.
- What stops a customer being charged twice?
- Idempotency. Every payment event is recorded against the provider reference inside a database transaction, and a handler that sees a reference it has already processed does nothing. Combined with row locks on balance changes, a duplicate event cannot double-charge, double-credit or double-pay.
- Why does money need to be stored as integers?
- Because 0.1 plus 0.2 does not equal 0.3 in floating point. Storing GHS 1.00 as 100 pesewas makes every amount exact. Rounding then happens once, deliberately, at defined points rather than accumulating silently across a ledger.