Skip to content

Payout API Request Builder

Copy-paste code to send money to mobile money wallets with Paystack (Ghana, Kenya) or Flutterwave (Uganda), in four languages. The network code, the amount format and the reference are checked as you type. Everything runs in your browser.

Request

Provider
Step

Code

    Expected response
    Then
    Your .env file

    PHP output reads config('services.paystack.secret_key') or config('services.flutterwave.secret_key'): map them to these variables in config/services.php.

    How a mobile money payout works

    Both providers send money from your balance to a wallet, and both answer straight away with "queued". The result comes later, so the request on its own never means the money arrived.

    PaystackFlutterwave (v3)
    Countries hereGhana (MTN, Telecel, AT), Kenya (M-Pesa)Uganda (MTN, Airtel)
    Before the first payoutCreate a recipient once per wallet (POST /transferrecipient)Nothing: the number goes in each transfer
    SendPOST /transferPOST /v3/transfers
    AmountSubunits: 25.50 GHS is 2550Whole shillings: 50000
    Phone formatLocal: 0551234987With the country code: 256772123456
    Look it upBy your reference: GET /transfer/verify/:referenceBy their id: GET /v3/transfers/:id
    Final statusessuccess, failed, reversed, abandoned, blocked, rejectedSUCCESSFUL, FAILED

    After a timeout: the one rule that matters

    A timed-out payout request may still have gone through. Never send it again with a new reference: that can pay twice. On Paystack, verify it by your reference; if Paystack has never seen it, send it again with the same reference. On Flutterwave, you need the transfer id to look it up, and a lost response means you don't have it. Mark the payout unknown and wait for thetransfer.completed webhook, which carries your reference and the id. Flutterwave's docs say a timeout is a 503 after about 28 seconds and the transfer may still be processing.

    Before you send real money

    • Paystack transfers need a registered business. Transfers need an OTP by default: untick Confirm transfers before sending in Preferences to send from code.
    • Paystack's docs don't state the phone format for Kenyan recipients. The builder uses the local format, as in its Ghana example: confirm it with one small live payout.
    • Flutterwave's mobile money page lists Airtel, MPS and MTN for Uganda. The builder sends MTN or Airtel, picked from the number; confirm it in test mode.
    • Save each payout, with its reference, in your database before sending it, and only ever send from a "new" status.

    What each status and error means: Paystack error reference and Flutterwave error reference.

    Frequently asked questions

    What bank_code do I use for a mobile money wallet on Paystack?

    The network: MTN, VOD (Telecel) or ATL (AT) in Ghana, and MPESA in Kenya, with type mobile_money. This builder picks the code from the phone number. You can list the codes on your account with GET /bank?currency=GHS&type=mobile_money.

    Why is my Paystack transfer amount 100 times too small?

    Paystack amounts are in the subunit: pesewas for GHS, cents for KES. 25.50 GHS is sent as 2550. The builder converts the amount you type, without floating point.

    My transfer request timed out. Can I send it again?

    On Paystack, verify it by your reference first, and only send again, with the same reference, if Paystack has never seen it. On Flutterwave you look transfers up by their id, which you don't have if the response was lost, so don't resend: wait for the transfer.completed webhook, which carries your reference and the id.

    Is "Transfer has been queued" or "Transfer Queued Successfully" a completed payout?

    No. Both mean the provider accepted the transfer. It is complete only when the lookup says success (Paystack) or SUCCESSFUL (Flutterwave). On Paystack, a success can still become reversed later.

    Is it safe to paste my secret key here?

    The page runs entirely in your browser and sends nothing anywhere, but only ever use a test key. Live keys are refused and left out of the code. The default is to read the key from an environment variable.

    Full integrations

    Endpoints and fields checked November 2026 against Paystack's transfer documentation and Flutterwave's v3 documentation.

    Need this built for you?

    I integrate MTN MoMo, M-Pesa and Airtel Money into Laravel / PHP, Python / Django, Node.js / Next.js apps: payments, callbacks, payouts and go-live, with tests.