🇪🇺 Whitelist-ready egress for Flutterwave transfers

Static IP for Flutterwave

Flutterwave's payouts checklist tells you to whitelist the servers that make Transfer API calls. Route those calls through two fixed static EU IPs, add them once under Whitelisted IP addresses, and every transfer leaves from an address the dashboard already trusts.

payout-service · shell

# one variable pins egress on every surface

export HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443

# every call now leaves from the trusted pair

curl -s -X POST "https://api.flutterwave.com/v3/transfers" \

  -H "Authorization: Bearer $FLW_SECRET_KEY" \

  -H "Content-Type: application/json"

# Bearer, one space, then the FLWSECK key

The checklist is short. Your egress is the hard part.

Flutterwave frames whitelisting as extra security and control for your payouts, and its integration docs make the assignment explicit. The only input the dashboard asks for is the one thing cloud infrastructure refuses to give you: addresses that hold still.

Step two of the payout checklist

Before your first transfer, the docs list two prerequisites: enable Transfer via API in your dashboard settings, then "whitelist the IP addresses of the servers that will be making Transfer API calls." There is no shortcut through step two. The dashboard expects named addresses, and it is your infrastructure that has to produce them.

Every edit costs an OTP

Each add or remove under Whitelisted IP addresses finishes with a one-time passcode delivered by email or WhatsApp. That is fine twice a year and unbearable per deploy: an egress address that rotates drags a two-channel confirmation ritual into the middle of your payout pipeline, with a WhatsApp dependency nobody asked for.

Cloud egress will not hold still

Autoscaled pods, serverless functions, and platform-hosted jobs leave from pooled or per-instance addresses that reshuffle on every schedule. The dashboard's format dropdown wants explicit IPv4 or IPv6 entries, and a fleet that changes shape hourly has no honest answer to that question.

Two directions, one whitelist habit

Flutterwave is explicit that its own webhook source IPs are dynamic and recommends signature verification over IP rules for inbound traffic. So address discipline belongs on exactly one side of the integration: the outbound Transfer API calls that carry your money out. That is the side with no publisher ranges, no signatures, just the list you maintain.

The Solution

Two fixed EU IPs the dashboard lists once and keeps trusting

Your Platform

transfers · payouts · bulk

HTTPS Proxy

(Static EU IP)

Flutterwave

api.flutterwave.com/v3

Enter both fixed addresses once under Whitelisted IP addresses, confirm a single OTP, and the checklist item is closed for good: transfers initiate from an address the dashboard was told to trust, and failover between the pair never reopens the question.

Declare HTTPS_PROXY once in your platform's environment; single transfers, bulk runs, and beneficiary calls then leave from your fixed pair.
Both addresses live in the list, so they cover for each other. One proxy node stepping out is invisible to Flutterwave and to the payouts queued behind it.
TLS runs straight through to Flutterwave. Your FLWSECK secret travels as a Bearer token inside encryption the proxy never unwraps.

Why payout teams route Flutterwave through OutboundGateway

Prerequisites cleared in one sitting

Flip Transfer via API on, paste two addresses, confirm one OTP, and both items on the payouts checklist are done before the first test transfer. No phased rollout, no per-environment negotiations with the dashboard.

Scale without OTP churn

Two addresses cover every pod, region, function, and cron job you will ever deploy. The whitelist stays two entries long whether you run three servers or three hundred, and no scaling event ever ends in an email-and-WhatsApp confirmation.

One pair across every payout rail

Flutterwave is one rail among many, and the same two EU addresses answer every PSP's whitelist question. Our Paystack static IP guide and Razorpay guide walk the identical pattern on the neighboring rails.

Designed for

Anyone pushing money out through Flutterwave's Transfer API who wants the whitelist step finished once instead of tended forever.

Marketplaces and SaaS paying out widely

Seller settlements, refunds as transfers, and bulk payout runs to bank accounts, mobile money, or other Flutterwave wallets across Nigeria, Ghana, Kenya, the UK, SEPA, and 30-plus countries, all initiated from one trusted pair.

Finance-ops batch jobs

Cron-driven bulk transfers and status polling run when nobody is watching. An origin the dashboard does not recognize is a payroll run that stalls overnight, discovered by an angry beneficiary rather than a dashboard alert.

Fintechs and agencies building for merchants

Every client dashboard gets the same two addresses in its whitelist, so the integration you built once works identically across every account you operate, and client onboarding never restarts the address conversation.

Platforms graduating from test keys

Test keys carry the _TEST prefix and forgive a lot. The day you switch to live FLWSECK credentials and flip Transfer via API on is the day the whitelist earns its keep, so the pair should already be in place.

Implementation

One environment variable routes every transfer request out of your fixed EU address.

Shell / environment

Set the variable wherever your payout jobs run. Flutterwave authenticates with your secret key as a Bearer token, and the header is unfussy in exactly one way: Bearer, a single space, then the key.

# .env, task definition, Kubernetes secret, wherever env config lives
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
FLW_SECRET_KEY=FLWSECK-xxxxxxxxxxxxxxxxxxxxxxxx-x

# create a transfer, egressing from your static EU IP
curl -s -X POST "https://api.flutterwave.com/v3/transfers" \
  -H "Authorization: Bearer $FLW_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"account_bank":"044","account_number":"0690000040",
       "amount":5500,"currency":"NGN",
       "reference":"payout-2026-10-31-001"}'

# reference is your unique id; you query transfer status with it

Python (requests)

requests reads HTTPS_PROXY from the environment on its own, so there is no proxy argument to wire and nothing to hardcode: credentials come from os.environ, the way Flutterwave's own docs recommend storing them.

import os
import requests

transfer = {
    "account_bank": "044",
    "account_number": "0690000040",
    "amount": 5500,
    "currency": "NGN",
    "reference": "payout-2026-10-31-001",
}

res = requests.post(
    "https://api.flutterwave.com/v3/transfers",
    headers={"Authorization": f"Bearer {os.environ['FLW_SECRET_KEY']}"},
    json=transfer,
)

print(res.json()["status"])  # env proxy rides along, egress is your fixed pair

Node.js (undici ProxyAgent)

Node's built-in fetch ignores proxy env vars, so hand it undici's ProxyAgent explicitly. If you use the official flutterwave-node-v3 SDK, keys are provided when the client is initialized and Transfer.initiate() fires the same POST underneath.

import { ProxyAgent } from 'undici';

const res = await fetch('https://api.flutterwave.com/v3/transfers', {
  method: 'POST',
  dispatcher: new ProxyAgent(process.env.HTTPS_PROXY),
  headers: {
    Authorization: `Bearer ${process.env.FLW_SECRET_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    account_bank: '044',
    account_number: '0690000040',
    amount: 5500,
    currency: 'NGN',
    reference: 'payout-2026-10-31-001',
  }),
});

Whitelist the pair in the dashboard

The ceremony is short and, with a fixed pair, rare: both addresses go in once, the OTP confirms the change, and the list never needs a third visit.

# dashboard -> Settings -> Whitelisted IP addresses
#   -> Add IP Address
#   enter BOTH fixed IPv4 addresses, one entry each
#   pick IPv4 in the format dropdown (IPv6 also supported)
#   OTP arrives via email or WhatsApp to confirm the change

# control stays yours: removing an address from the
#   same list revokes it anytime

# done once; the pair does not move under you, so the
#   OTP only happens when YOU change the list

Both IPs belong in the list from day one

Every account gets its own pair of static EU IPv4 addresses. Add both, confirm one OTP, and a proxy failover between them is a non-event: the other address was already trusted, so transfers continue while you read about it later. The next environment you wire up is the same two-line paste.

Which traffic is covered? Everything here is your outbound, Bearer-authenticated REST traffic to api.flutterwave.com/v3: creating transfers, queuing bulk runs, polling transfer statuses, and managing beneficiaries. The whitelist item sits in the payouts checklist, so it is this money-moving traffic it protects. Webhooks run the other direction, Flutterwave POSTing events to your endpoint, and their docs recommend verifying webhook signatures rather than filtering IPs, so nothing inbound flows through the proxy.

📖 Complete Documentation: For detailed examples, error handling, and advanced configurations, see the Python guide, the Node.js guide, or all guides.

Payout traffic with a European origin

Flutterwave's transfer rails reach more than 30 countries, EUR transfers included across the SEPA area. Wherever the money lands, the server it departs from can be European, and that part of the journey is yours to choose.

GDPR, starting at the source

Transfer payloads carry beneficiary names, account numbers, narrations, and references, personal and financial data in one request body. Egress from EU data centres gives that data a European origin for its entire trip to the API, which keeps the residency story simple when compliance asks where payout calls physically start.

PCI DSS posture, sealed credentials

Payout integrations live in a card-and-bank rails world where PCI DSS frames how the chain is secured, and Flutterwave is blunt that the secret key can do anything on the account. Yours travels as a Bearer token inside TLS the proxy passes through untouched, stored as an env var, never in a repo or a frontend.

What you get

A checklist item that stays done

Whitelisting your servers is a prerequisite, not a subscription. A fixed pair turns it into something you finish in the first hour and never revisit, no matter how the fleet behind it evolves.

One paste, zero OTP chases

Both addresses enter the list once with a single confirmation. Deploys, scale events, and node recycling stop generating email-and-WhatsApp rituals, because the egress simply never changes.

Failover without a dashboard event

Both IPs sit in the whitelist from the first day, so the proxy switching between them is invisible to Flutterwave. Transfers keep flowing while the failover happens, and the OTP stays unhunted.

Revocation stays yours

The dashboard lets you remove an address anytime, and that control is worth keeping. The pair works for as long as you list it and stops the moment you take it out, with no lock-in in either direction.

Secrets sealed end to end

You attach the Bearer token on your side, and TLS passthrough carries it to Flutterwave encrypted. The proxy relays ciphertext and nothing else, so the key that can do anything on the account is seen by no one in between.

Simple pricing

Starting from €19/month. Flexible plans for every scale. Cancel anytime.

Paste the pair once, let the fleet churn

A single environment variable points every Transfer API call at two fixed EU addresses your dashboard already trusts, from the first test payout to the thousandth bulk run.

Starting from €19/month. Flexible plans for every scale. Cancel anytime.

Frequently asked questions

Does Flutterwave support IP whitelisting?

Yes. Under Settings on your dashboard, the Whitelisted IP addresses page lets you add addresses one at a time, choosing IPv4 or IPv6 from a format dropdown, with each change confirmed by an OTP sent via email or WhatsApp. Flutterwave presents it as added security and control for your payouts, and the Transfer API integration checklist asks you to whitelist the servers that will be making Transfer API calls before you start. You keep full control and can revoke an address by removing it anytime.

How do I add the proxy IPs to my Flutterwave dashboard?

Open Settings, then Whitelisted IP addresses, and click Add IP Address. Enter both fixed EU IPv4 addresses from your OutboundGateway account, one entry each, pick IPv4 in the format dropdown, and confirm the OTP that arrives by email or WhatsApp. That single session finishes the setup: both addresses answer for your traffic, so a failover between them needs no dashboard visit, and the list only changes again if you decide to change it.

Do Flutterwave webhooks also need the proxy?

No. Webhooks are inbound: Flutterwave POSTs event notifications to an endpoint you expose, and your outbound proxy plays no role in that direction. Flutterwave's own docs note that their source IPs are dynamic and recommend verifying webhook signatures rather than filtering by IP, so the address discipline applies to your outbound Transfer API calls, which is exactly the traffic the proxy and the whitelist cover.

The two addresses your payout checklist is waiting for

Tell us what your Flutterwave integration runs on, and we will map exactly where the pair plugs in.

Contact Our Founders →