🇪🇺 Predictable egress for payment APIs

Static IP for CinetPay

Your backend talks to CinetPay all day: OAuth logins, payment initializations, status checks on api.cinetpay.co. Give those credential-bearing calls two fixed static EU IPs with one HTTPS_PROXY variable, so your integration keeps one predictable, attributable origin.

checkout-backend · shell

# one-time setup

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

# 1. authenticate (leaves from your static EU IP)

curl -s -X POST https://api.cinetpay.co/v1/oauth/login \

  -d '{"api_key":"sk_live_...","api_password":"..."}'

# 2. initiate a payment, Bearer in hand

curl -s -X POST https://api.cinetpay.co/v1/payment \

  -H "Authorization: Bearer $TOKEN" \

  -d '{"amount":5000,"currency":"XOF"}'

A payment integration deserves a stable identity

CinetPay's API authenticates you with keys and tokens. The address your requests come from is the part you don't control, until now.

Every deploy changes your address

Heroku dynos, Vercel functions, and Lambda workers each restart with fresh egress IPs. Your payment initializations on api.cinetpay.co arrive from a different machine almost daily, and nothing on your side can say what your integration's address is.

Every call carries credentials

Each request sends a Bearer access_token minted from your sk_live_ key. When the source address rotates, you cannot scope firewall rules, WAF entries, or log alerts to the one system that moves money.

Support tickets go in circles

A webhook that never landed or a payment stuck in PENDING means combing logs for your own requests. When the source address keeps moving, matching what your monitoring saw with what CinetPay received is guesswork.

Payment integrations get audited

Security questionnaires and internal reviews ask where payment traffic originates and how you limit it. "Wherever the platform put us today" is not an answer an auditor accepts from the system that initiates transactions.

The Solution

One fixed EU IP pair for every call to api.cinetpay.co

Your Backend

payment init + status polls

HTTPS Proxy

(Static EU IP)

CinetPay API

api.cinetpay.co

CinetPay sees every request your backend makes arriving from the same two EU addresses, whichever platform runs it. One address backs up the other, so maintenance on a proxy node never changes the origin your logs and monitoring record.

Set HTTPS_PROXY once in your backend's environment; every OAuth login, payment initialization, and status check then leaves from your fixed address.
Two EU addresses back each other up. If either proxy node blinks out, the other keeps answering, so the origin never surprises you mid-transaction.
TLS passes straight through to CinetPay. Bearer tokens and payment payloads arrive encrypted, never visible at the proxy.

Why payment teams route CinetPay traffic through OutboundGateway

Attributable by design

The egress address becomes the integration's identity. Firewall rules, log alerts, and audit questions about your CinetPay traffic finally have one stable answer.

Built around the real flow

Wired for the documented v1 sequence: POST /v1/oauth/login, POST /v1/payment with the Bearer token, and GET /v1/payment/{id} status polls. No SDK surgery required.

European egress

Requests exit from EU data centres, so an EU-headquartered merchant keeps a clean data-residency story even while collecting payments across African markets.

Designed for

Teams whose CinetPay integration has to look predictable, to their own tooling and to anyone reviewing it.

PaaS and serverless checkouts

Backends on Heroku, Vercel, Railway, or Lambda that initiate CinetPay payments and cannot promise a stable egress address on their own.

Reconciliation and polling jobs

Cron workers that poll GET /v1/payment/{id} until transactions settle and need their traffic identifiable in logs and firewalls.

Agencies building for African markets

Shops and apps that collect via CinetPay mobile money and card checkout, and want their backend's outbound calls pinned to two known addresses.

Security-reviewed payment teams

Integrations that must answer where transaction-initiation traffic originates and how it is contained to a known address pair.

Implementation

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

Shell / environment

Set the variable wherever your backend 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

# authenticate and initiate, now from your static EU IP
TOKEN=$(curl -s -X POST https://api.cinetpay.co/v1/oauth/login \
  -H "Content-Type: application/json" \
  -d '{"api_key":"sk_live_...","api_password":"..."}' \
  | jq -r .access_token)

curl -s -X POST https://api.cinetpay.co/v1/payment \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"amount":5000,"currency":"XOF","merchant_transaction_id":"ORDER-042","notify_url":"https://app.example.com/webhooks/cinetpay"}'

Python (requests)

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

import os, requests

# authenticate
login = requests.post("https://api.cinetpay.co/v1/oauth/login", json={
    "api_key": os.environ["CINETPAY_API_KEY"],
    "api_password": os.environ["CINETPAY_API_PASSWORD"],
}).json()

# initiate a payment, egressing from your static EU IP
payment = requests.post(
    "https://api.cinetpay.co/v1/payment",
    headers={"Authorization": f"Bearer {login['access_token']}"},
    json={"amount": 5000, "currency": "XOF"},
).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.cinetpay.co/v1/payment', {
  dispatcher,
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify({ amount: 5000, currency: 'XOF' }),
});

Sandbox works the same

Test traffic targets api.cinetpay.net with sk_test_ keys. The proxy variable does not change.

# same HTTPS_PROXY, sandbox host and test keys
curl -s -X POST https://api.cinetpay.net/v1/oauth/login \
  -d '{"api_key":"sk_test_...","api_password":"..."}' | jq -r .access_token

Register both addresses on your own side

Your account ships with a pair of static EU IPs. Add them to your own firewall allowlists, WAF rules, and monitoring so CinetPay-bound traffic is identifiable end to end. And if CinetPay support or onboarding ever asks which addresses to expect from you, the answer is already stable.

Which traffic is covered? Only your backend's outbound calls to api.cinetpay.co or api.cinetpay.net. The checkout popup runs in your customer's browser on secure.cinetpay.co, and payment notifications arrive inbound at your notify_url; neither touches the proxy.

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

EU egress for payment traffic

When your backend forwards payment instructions and customer details, the path matters as much as the destination.

GDPR-conscious routing

Your requests exit through European data centres, keeping the transfer story simple for an EU-headquartered merchant collecting across African markets.

TLS straight through

The connection to CinetPay is never terminated at the proxy. Bearer tokens, customer names, and payment payloads stay encrypted the whole way.

What you get

Two addresses, one identity

A pair of static EU IPs covering for each other, so your integration's origin survives a proxy node restart.

Survives redeploys

Dyno restarts and function cold starts stop mattering; the address pair stays put while everything behind it churns.

End-to-end encryption

TLS passthrough keeps tokens and payment payloads sealed past the proxy hop.

Runtime-agnostic

One env var covers curl, Python requests, Node with undici, and PHP backends alike.

Ready for any allowlist

Hand the same pair to partners, auditors, or your own firewalls whenever the question comes up.

Honest pricing

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

Give your CinetPay integration one stable origin

Set one environment variable and every payment initialization, OAuth login, and status poll leaves from two fixed EU addresses.

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

Frequently asked questions

Does CinetPay support IP whitelisting?

Not in their public documentation. CinetPay's documented security model rests on API key secrecy, separate sandbox and production keys, and webhook verification, and their merchant dashboard exposes no IP allowlist that we could find. The reason to run a static IP here is your side of the conversation: attributable egress, tighter firewall scoping, and a ready answer if their team ever asks which addresses to expect from you.

Which CinetPay traffic goes through the proxy?

Only your backend's outbound calls: POST /v1/oauth/login, POST /v1/payment, and GET /v1/payment/{id} against api.cinetpay.co. The checkout popup runs in your customer's browser on secure.cinetpay.co, and payment notifications arrive inbound at your notify_url; neither touches the proxy.

Does it work with the CinetPay sandbox?

Yes. Sandbox traffic targets api.cinetpay.net with sk_test_ keys, and the same HTTPS_PROXY variable covers it. You switch keys, not configuration, between sandbox and production.

Running CinetPay on a platform that rotates egress?

Happy to talk through how a managed EU proxy pair fits your checkout backend.

Contact Our Founders →