🇪🇺 Whitelist-ready egress for Paystack integrations

Static IP for Paystack

Paystack can block every secret key request that leaves from an address you did not whitelist. Give it two fixed static EU IPs with one HTTPS_PROXY variable, and switch that whitelist on for good, in production and in test.

payments-platform · shell

# one variable, fixed egress for every call

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

# initialize a checkout with your secret key

curl -s -X POST https://api.paystack.co/transaction/initialize \

  -H "Authorization: Bearer $PAYSTACK_SECRET_KEY" \

  -d '{"email":"customer@email.com","amount":"20000"}'

# verify it, from the same two EU IPs

curl -s https://api.paystack.co/transaction/verify/$REFERENCE \

  -H "Authorization: Bearer $PAYSTACK_SECRET_KEY"

The whitelist wants stable addresses. Your platform has none.

Paystack's IP whitelisting is a genuinely good control: once a list is set, secret key calls from anywhere else are blocked. It only works if the addresses on it never change.

Rotating egress defeats the whole feature

Containers, Kubernetes pods, and serverless functions restart with fresh egress IPs. Add one address and the next deploy is locked out; add none and a leaked live secret key still works from any machine on earth. Plenty of teams run with whitelisting off for exactly this reason.

Live and test keys, two lists to keep in sync

Whitelists are tied to your secret keys, with separate lists for live and test. CI runners and staging platforms egress from whatever address their host assigned today, and a drift between the two lists quietly locks a Friday deploy out of api.paystack.co.

Ten slots, single IPv4 addresses only

Paystack accepts valid public IPv4 addresses: no CIDR ranges, no IPv6, no private addresses, and at most ten per list. You cannot paste in a cloud provider's rotating egress range even if you knew it. The form wants concrete addresses that are actually yours.

A blocked call is a broken checkout

Initializing a transaction, verifying a reference, charging a saved authorization: these run mid-checkout and in unattended recurring jobs at night. A request from the wrong origin is not retried gracefully. It is refused in front of a paying customer.

The Solution

One fixed EU IP pair for everything you send to api.paystack.co

Your Platform

initialize + verify + charge calls

HTTPS Proxy

(Static EU IP)

Paystack API

api.paystack.co

Both addresses go on the whitelist under "+Add IP address", on the live key's list and on the test key's. Paystack then sees every request from your platform arriving at one of two EU addresses, whichever runtime issued it, and either address can carry the whole load.

Set HTTPS_PROXY once in your platform's environment; every initialize, verify, charge and export call then leaves from your fixed pair.
Two IPv4 addresses stand in for each other. If either proxy node drops out, the other keeps answering, so the origin your whitelist records never changes.
TLS passes straight through to Paystack. Your secret key stays encrypted past the proxy hop; we never see it.

Why payment teams route Paystack traffic through OutboundGateway

A switch you can finally flip on

IP whitelisting only protects you if it stays enabled. A pair of addresses you actually own is what makes leaving it on compatible with serverless deploys, autoscaling, and everything else that reshuffles your egress.

Fits the documented API surface

Wired for the real endpoints: a Bearer secret key header, POST /transaction/initialize, GET /transaction/verify/{reference}, charge_authorization for saved authorizations. No SDK surgery required.

Discipline in both directions

Paystack publishes the source IPs its webhooks come from, so you can pin inbound traffic. Your outbound secret key calls deserve the same treatment. Paystack has been part of Stripe since 2020; see our Stripe static IP guide for the same pattern on the parent platform.

Designed for

Teams collecting payments through Paystack who want the whitelist on, and their egress to finally cooperate with it.

Platforms selling into African markets

Checkouts over NGN, GHS and KES with channels like USSD, mobile money and bank transfer. If you also collect through CinetPay, the same address pair covers both integrations.

Subscription and recurring billing teams

Scheduled charge_authorization calls run unattended against saved authorizations overnight. A locked-out origin fails quietly until the morning dunning report notices.

Teams with separate staging and production

Live and test secret keys carry separate whitelists. Putting the same pair on both lists means identical proxy configuration ships to every environment, and the test list never drifts.

Security teams hardening live keys

PCI-DSS-scoped reviews ask how a leaked secret key would be contained. A whitelist of two IPv4 addresses is not a hope; it is a rule Paystack actively enforces on every request.

Implementation

One environment variable, and your Paystack calls leave from a fixed EU address.

Shell / environment

Set the variable wherever your platform runs. curl picks it up with no other change.

# .env, Heroku config vars, Vercel env settings, Lambda env
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443

# initialize a checkout, from your static EU IP
curl -s -X POST https://api.paystack.co/transaction/initialize \
  -H "Authorization: Bearer $PAYSTACK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"customer@email.com","amount":"20000"}' \
  | jq -r .data.authorization_url

# amounts are passed in subunits (kobo, pesewas, cents)

Python (requests)

requests reads HTTPS_PROXY from the environment automatically; keep your secret key in os.environ.

import os, requests

headers = {"Authorization": f"Bearer {os.environ['PAYSTACK_SECRET_KEY']}"}

# initialize a transaction, egressing from your static EU IP
txn = requests.post(
    "https://api.paystack.co/transaction/initialize",
    headers=headers,
    json={"email": "customer@email.com", "amount": 20000},
).json()

# verify it lands on the same two EU IPs
verified = requests.get(
    f"https://api.paystack.co/transaction/verify/{txn['data']['reference']}",
    headers=headers,
).json()

Node.js (undici ProxyAgent)

Node's native fetch ignores proxy env vars; hand it undici's ProxyAgent instead.

import { ProxyAgent } from 'undici';

const dispatcher = new ProxyAgent(process.env.HTTPS_PROXY);

const res = await fetch('https://api.paystack.co/transaction/initialize', {
  method: 'POST',
  dispatcher,
  headers: {
    Authorization: `Bearer ${process.env.PAYSTACK_SECRET_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ email: 'customer@email.com', amount: 20000 }),
});

Test keys, same pair

Whitelists are per key type. Add the same two addresses to the test key's list and identical configuration works in CI, staging and production.

# same HTTPS_PROXY, test-mode secret key
curl -s https://api.paystack.co/transaction \
  -H "Authorization: Bearer $PAYSTACK_TEST_SECRET_KEY"

Register both addresses in Paystack

Your account ships with a pair of static EU IPv4 addresses. In the Paystack dashboard, open the API Keys and Webhook Settings tab and add both under "+Add IP address", once for the live key and once for the test key. That is two of ten slots used. Paystack emails the integration owner when the live list changes, so you always have an audit trail.

Which traffic is covered? Your platform's outbound secret-key calls: initialize, verify, charge_authorization, list and export. Paystack webhooks arrive inbound at your endpoints from published source addresses (52.31.139.75, 52.49.173.169, 52.214.14.220); allowlist those on your own firewall and verify the x-paystack-signature header (HMAC-SHA512) rather than routing webhooks through the proxy.

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

African payment rails, European egress

Paystack connects you to cards, bank transfers, USSD and mobile money across Nigeria, Ghana, Kenya, South Africa and beyond. Where those requests leave from is still your decision.

GDPR-conscious routing

Paystack was founded in Lagos and has been part of Stripe since 2020. Your outbound hop stays in EU data centres, keeping one simple residency story for the customer data riding in your API calls.

TLS straight through

The connection to Paystack is never terminated at the proxy. Your secret key, authorization codes and payment payloads stay encrypted the whole way.

What you get

Whitelist-ready by design

Two single public IPv4 addresses, exactly what the "+Add IP address" form accepts. No ranges needed, and none are allowed.

Survives redeploys

Pod reschedules and function cold stops stop mattering; the address pair stays put while everything behind it churns.

End-to-end encryption

TLS passthrough keeps your secret key, authorization codes and payloads sealed past the proxy hop.

Live and test covered

The same pair fits both per-key whitelists, with room to spare: two of ten slots on each list.

Built for real endpoints

Initialize, verify, charge_authorization, export: the exact calls your checkout and reconciliation jobs already make.

Honest pricing

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

Give your Paystack integration one stable origin

Set one environment variable and every initialize, verify and charge call leaves from two fixed EU addresses that fit the whitelist.

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

Frequently asked questions

Does Paystack support IP whitelisting?

Yes. In the dashboard's API Keys and Webhook Settings you add allowed addresses with "+Add IP address". Once a list is set, secret key requests from any other address are blocked. Each list holds up to ten valid public IPv4 addresses, and live and test keys keep separate lists. Dashboard logins are not affected, and Paystack emails the integration owner whenever the live list changes.

Do both proxy IPs fit the whitelist?

Yes. You get two single public IPv4 addresses, and each list holds up to ten. Add both: either address can carry your entire traffic, so a proxy node failing over never changes the origin your whitelist records, and the list itself never needs touching.

What about webhooks from Paystack?

They arrive inbound, from Paystack's published source addresses (52.31.139.75, 52.49.173.169, 52.214.14.220). Allowlist those on your firewall and verify each payload's x-paystack-signature header, an HMAC-SHA512 of the body keyed with your secret key. The proxy covers your outbound API calls, not Paystack's deliveries to you.

Running Paystack on a platform that rotates egress?

Happy to talk through how a managed EU proxy pair fits your payment platform.

Contact Our Founders →