Integrate with Flutterwave's payment API for pan-African commerce. Use this skill whenever the user wants to accept payments across multiple African countries, process mobile money payments, handle card charges, create payment links, issue virtual cards, send payouts/transfers, or work with Flutterwave (Rave) in any way. Also trigger for 'Flutterwave', 'Rave', 'African mobile money', 'pan-African payments', 'multi-currency Africa checkout', or when the user needs to support payments in Nigeria, Ghana, Kenya, South Africa, Tanzania, Uganda, and 30+ other African markets simultaneously.
Flutterwave is Africa's leading pan-African payment infrastructure, supporting 150+ currencies and multiple payment methods across 30+ African countries. It handles card payments, mobile money (M-Pesa, MTN MoMo, Airtel Money), bank transfers, USSD, and more — all through a single API.
You're building something that needs to accept or send payments across Africa — not just one country. A marketplace connecting buyers and sellers across borders, a SaaS serving multiple African markets, a remittance product, or anything where multi-country coverage matters. Flutterwave is the "one API for all of Africa" play.
All requests require your secret key as a Bearer token:
Authorization: Bearer FLWSECK_TEST-xxxxx
Keys: FLWSECK_TEST- for sandbox, FLWSECK- for production. Store in FLUTTERWAVE_SECRET_KEY env var.
Base URL: https://api.flutterwave.com/v3
⚠️ v3 vs v4: This skill documents the v3 API, which is fully functional and widely used. Flutterwave launched v4 in 2024 with OAuth 2.0 authentication (
https://idp.flutterwave.com/realms/flutterwave/protocol/openid-connect/token) and updated sandbox URLs (https://developersandbox-api.flutterwave.com). If you are starting a new integration and your dashboard offers v4 credentials, prefer v4. The v3FLWSECK_secret key auth described here will continue to work for existing integrations.
The simplest way to collect payments — create a payment link and redirect the customer.
POST /payments
{
"tx_ref": "txn_unique_ref_123",
"amount": 5000,
"currency": "NGN",
"redirect_url": "https://yoursite.com/payment/callback",
"customer": {
"email": "[email protected]",
"name": "Amina Okafor",
"phonenumber": "+2348012345678"
},
"customizations": {
"title": "My Store",
"description": "Payment for Order #123",
"logo": "https://yoursite.com/logo.png"
},
"payment_options": "card, mobilemoney, ussd, banktransfer",
"meta": {
"order_id": "ORD-123"
}
}
Important: Amounts are in the major currency unit (not kobo/pesewas). ₦5000 = 5000, not 500000.
Response:
{
"status": "success",
"message": "Hosted Link",
"data": {
"link": "https://checkout.flutterwave.com/v3/hosted/pay/xxxxx"
}
}
Redirect customer to data.link. After payment, they return to redirect_url?tx_ref=txn_unique_ref_123&transaction_id=12345&status=successful.
For direct mobile money integration (M-Pesa, MTN MoMo, etc.):
POST /charges?type=mobile_money_kenya
{
"tx_ref": "mm_ref_123",
"amount": 1000,
"currency": "KES",
"email": "[email protected]",
"phone_number": "254712345678",
"network": "Safaricom"
}
Types by country and supported networks:
mobile_money_kenya (M-Pesa via Safaricom)mobile_money_ghana (MTN, Vodafone, Airtel)mobile_money_uganda (MTN, Airtel)mobile_money_rwanda (MTN, Airtel)mobile_money_tanzania (Airtel, Tigo, Halopesa)mobile_money_franco (MTN, Orange, Wave)mobile_money_franco (Orange, Free Money, Wave)mobile_money_franco (Airtel, MTN, Zamtel)Response includes a redirect URL or requires OTP validation depending on the provider.
For direct card integration (PCI DSS compliant environments only):
POST /charges?type=card
{
"tx_ref": "card_ref_123",
"amount": 5000,
"currency": "NGN",
"email": "[email protected]",
"card_number": "4187427415564246",
"cvv": "828",
"expiry_month": "09",
"expiry_year": "32",
"fullname": "Amina Okafor",
"enckey": "your_encryption_key"
}
Card data must be encrypted with AES-256 using your encryption key. Retrieve your encryption key from your Flutterwave dashboard API settings. Response may require pin, otp, redirect (3DS), or avs_noauth — handle each meta.authorization.mode accordingly.
Always verify server-side:
GET /transactions/{transaction_id}/verify
Response:
{
"status": "success",
"data": {
"id": 12345,
"tx_ref": "txn_unique_ref_123",
"flw_ref": "FLW-MOCK-xxxxx",
"amount": 5000,
"currency": "NGN",
"charged_amount": 5000,
"status": "successful",
"payment_type": "card",
"customer": {
"email": "[email protected]",
"name": "Amina Okafor"
}
}
}
Verify: data.status === "successful", data.amount and data.currency match your expected values.
GET /transactions?from=2025-01-01&to=2025-01-31&page=1&status=successful
Query params: from, to (YYYY-MM-DD), page, status, tx_ref, customer_email, currency.
For no-code payment pages:
POST /payment-plans
{
"amount": 10000,
"name": "Annual Subscription",
"interval": "monthly",
"currency": "NGN"
}
Intervals: daily, weekly, monthly, quarterly, yearly.
Send money to bank accounts or mobile money wallets:
POST /transfers
{
"account_bank": "044",
"account_number": "0690000040",
"amount": 5000,
"currency": "NGN",
"narration": "Seller payout",
"reference": "transfer_ref_123",
"debit_currency": "NGN"
}
For mobile money payouts:
{
"account_bank": "MPS",
"account_number": "254712345678",
"amount": 1000,
"currency": "KES",
"narration": "Driver payout",
"reference": "mm_payout_123",
"beneficiary_name": "John Kamau"
}
GET /banks/{country_code}
Country codes: NG (Nigeria), GH (Ghana), KE (Kenya), ZA (South Africa), TZ (Tanzania), UG (Uganda), RW (Rwanda), SN (Senegal), CM (Cameroon), CI (Côte d'Ivoire).
POST /virtual-cards
{
"currency": "USD",
"amount": 5000,
"billing_name": "Amina Okafor",
"billing_address": "123 Main St",
"billing_city": "Lagos",
"billing_state": "Lagos",
"billing_postal_code": "100001",
"billing_country": "NG",
"first_name": "Amina",
"last_name": "Okafor",
"date_of_birth": "1990/01/15",
"email": "[email protected]",
"phone": "+2348012345678",
"title": "Mr",
"gender": "F"
}
Set your webhook URL in the Flutterwave dashboard. Verify with the secret hash:
The verif-hash header Flutterwave sends is the literal secret hash value configured in your dashboard. Compare it directly — it is not an HMAC digest.
const secretHash = process.env.FLW_SECRET_HASH;
const signature = req.headers['verif-hash'];
if (!signature || signature !== secretHash) {
return res.status(401).send('Unauthorized');
}
// Process webhook
res.status(200).send('OK');
Critical: Return HTTP 200 status code to acknowledge receipt. Any other response code (including 3xx redirects) is treated as a failure.
Key events: charge.completed, transfer.completed, payment_plan.created, charge.updated.
Standard error response format:
{
"status": "error",
"message": "What went wrong",
"data": null
}
Common HTTP status codes and meanings:
message for detailsResponse codes in transaction responses:
0, 00, 02: SuccessresponseMessage for reasonImplement exponential backoff for 429/503 errors and always retry failed requests with unique transaction reference IDs.
3DS redirect mode for card transactions (not all cards authorize immediately)FLWSECK_ key: Your API authentication secret for making requests to the API (goes in Authorization header)FLW_SECRET_HASH: Your webhook verification hash configured in the dashboard. Flutterwave sends this exact value in the verif-hash header with every webhook. Compare directly — no HMAC computation required.mobile_money_* charge type* codes), others don'tGET /banks/{country_code} first to get valid bank codes before initiating transfers5000 (not 500000), $10 USD = 10 (not 1000)tx_ref values for each transaction attemptverif-hash header signature before trusting webhook dataFLWSECK_TEST- for all test transactions4187427415564246, CVV: 828, any future expiryPOST /payments with the customer's currency (NGN, KES, GHS, etc.)GET /transactions/{id}/verify server-sideGET /banks/{country} to get bank codes for target countryPOST /transfers to send to seller's bank or mobile moneyGET /transfers/{id}POST /payment-planspayment_plan ID when initializing paymentMajor markets: Nigeria (NGN), Ghana (GHS), Kenya (KES), South Africa (ZAR), Tanzania (TZS), Uganda (UGX), Rwanda (RWF), Cameroon (XAF), Côte d'Ivoire (XOF), Senegal (XOF), Egypt (EGP), and 20+ more.
Flutterwave is supported in Nigeria, Cameroon, Côte d'Ivoire, Egypt, Ghana, Kenya, Rwanda, Senegal, South Africa, Uganda, Tanzania, The United Kingdom, America, and Europe.