MustangPay checks every Payment API request against an IP whitelist that their support team binds manually. Route your integration through two fixed static EU IPs, have the pair bound once, and preorder and query calls keep arriving from addresses the gateway already admits.
# one variable pins egress on every surface
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
MUSTANGPAY_API_URL=https://<from-your-integration-pack>
# unlisted source IPs get an IP restriction
# error, so leave from the two bound addresses
curl -s "$MUSTANGPAY_API_URL/openApi/merchant_direct/cashier/preorder" \
-H "Content-Type: application/json" \
-d @preorder-envelope.json
The Payment API guide is unambiguous: requests are checked against the IP whitelist, only listed addresses are allowed through, and anything else receives an IP restriction error. The rule guards South African payment rails well. It just assumes your egress address can hold still.
The guide states that IP binding can only be done manually and requires contacting MustangPay support. There is no self-service field to edit at two in the morning, so every egress change waits on a person at the gateway while live traffic starts collecting IP restriction errors.
Their documentation asks both parties to configure IP whitelists in their respective systems. MustangPay admits only listed sources on your outbound calls, and their asynchronous notifications arrive from addresses you must admit on your own side, so two lists have to keep describing the same reality.
A preorder returns a cashier URL, the final result lands later as a notification on your callbackUrl, and the guide tells you to answer SUCCESS and actively call the order-status interface to confirm. Queries and re-checks keep leaving from whatever address your platform happens to have that day.
Every request body is sealed into a merchantId, encryptData, encryptKey triplet, RSA-signed and AES-GCM-encrypted before it ever leaves your stack. At the gateway the readable identity of the caller is the source address, and a drifting one turns a correctly signed request into a rejection.
Your Payment Stack
checkout backend · reconciliation jobs · cron workers
HTTPS Proxy
(Static EU IP)
MustangPay
mustangpay.co.za · Payment API
After MustangPay support binds the pair to your merchant account, every request your systems send arrives from the same two EU addresses, whether it left a container, a scheduled job, or a service that was redeployed an hour ago. Both sit in the whitelist, so a proxy node failing over changes nothing the gateway can see.
HTTPS_PROXY once in your environment and every Payment API call your stack makes, preorders, order-status queries, and retries alike, leaves through the same pair.aesKey, and the encrypted payload stay sealed past the proxy hop, and the gateway receives exactly what your code signed.With binding handled by a human on the gateway side, an infrastructure change usually means another ticket and another wait. Give them two addresses that never change and the conversation happens once, on your schedule, before the first production call goes out.
Preorders go out, notifications come back, and the order-status query follows to confirm the final state, sometimes hours later. Every outbound step in that rhythm leaves through the same fixed pair, so the address that opened the order is the address that confirms how it settled.
MustangPay already wraps request bodies in its RSA and AES-GCM envelope before transit. The proxy adds no decryption of its own: it relays the TLS session untouched, so signatures and ciphertext reach the gateway exactly as your code produced them.
Teams whose MustangPay traffic has to arrive recognized, on every call the integration makes.
MustangPay presents itself as a PASA-compliant TPPP sponsored by Nedbank, processing cards and bank transfers for South African merchants. European storefronts on EU infrastructure can call those rails without inheriting a rotating cloud egress as their caller identity.
Your code calls preorder, receives a redirectPayUrl on cashier-front.mustangpay.co.za, and hands the buyer to the hosted cashier. The outbound side is compact, which makes the address it leaves from the whole network story you have to keep consistent.
Settlement checks and order re-verification run on cron, long after the buyer closed the tab. Polling getOrderStatusByMerchantOrderNo from the bound pair means the overnight job knocks on the same front door as the afternoon checkout did.
Pods that reschedule and workers that spawn on demand have no stable address to name in any whitelist. A fixed pair in front of the fleet gives the support team two entries that cover every replica, present and future, as our Kubernetes static IP guide shows.
One environment variable routes every encrypted MustangPay envelope out of your fixed EU address.
Set the variables wherever your payment code runs. MustangPay publishes the API paths in its Payment API guide, and the environment domain arrives with your integration pack.
# .env, task definition, or Kubernetes secret, wherever env config lives
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
MUSTANGPAY_API_URL=https://<from-your-integration-pack>
# preorder call, now egressing from your static EU IP
curl -s "$MUSTANGPAY_API_URL/openApi/merchant_direct/cashier/preorder" \
-H "Content-Type: application/json" \
-d @preorder-envelope.json
# same pair for the integration-test and production environments
Plain requests picks up HTTPS_PROXY from the environment on its own, no extra wiring.
import os
import requests
# requests reads HTTPS_PROXY from the environment automatically
# body is the documented envelope: merchantId + encryptData + encryptKey
envelope = {
"merchantId": os.environ["MUSTANGPAY_MERCHANT_ID"],
"encryptData": seal_body(order), # AES-GCM, per the guide
"encryptKey": wrap_aes_key(), # RSA, per the guide
}
resp = requests.post(
f"{os.environ['MUSTANGPAY_API_URL']}/openApi/merchant_direct/cashier/preorder",
json=envelope,
)
resp.raise_for_status()
redirect = resp.json()["data"]["redirectPayUrl"]
# confirm final states later through
# /openApi/merchant_direct/cashier/getOrderStatusByMerchantOrderNo;
# every hop leaves from the same fixed pair
Node's built-in fetch ignores proxy environment variables, so hand it undici's ProxyAgent explicitly.
import { ProxyAgent } from 'undici';
const res = await fetch(
`${process.env.MUSTANGPAY_API_URL}/openApi/merchant_direct/cashier/preorder`,
{
dispatcher: new ProxyAgent(process.env.HTTPS_PROXY),
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: envelopeJson, // merchantId + encryptData + encryptKey
},
);
// the response hands back a redirectPayUrl for the hosted cashier;
// the fixed pair covers this call and every order-status query after it
Two addresses, one email, and the front door is settled for the life of the integration.
# binding the pair, once:
# collect BOTH fixed IPv4 addresses from your account
# email support@mustangpay.co.za requesting the whitelist
# binding for your merchantId
# support performs the manual binding on the gateway side
# whitelist MustangPay's notification source addresses inbound,
# per your integration pack, so their callbacks reach you
# the guide is literal about the failure mode: an IP that is not
# whitelisted gets an IP restriction error. With both addresses
# bound, redeploys, scale-outs, and region moves never produce one
One ticket, then the front door stays open
Every account gets its own pair of static EU IPv4 addresses. Have support bind both once, and the manual whitelist stops being a recurring project: redeploys, scale-outs, and new services all present the same two addresses, and a failover between nodes never reopens the conversation.
Which traffic is covered? Outbound HTTPS from your servers, containers, and scheduled jobs to MustangPay's Payment API: the preorder and order-status paths, in the integration-test and production environments alike. Asynchronous notifications run the other direction: MustangPay POSTs the final result to the callbackUrl you registered, your side answers with the string SUCCESS, and 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.
MustangPay operates from Crown Mines in Johannesburg under Mustang Financial (Pty) Ltd, presents itself as PCI-DSS Level 1 certified, and builds its privacy policy on South Africa's Protection of Personal Information Act. The origin of your side of each call is the part you control.
The privacy policy commits to POPIA, the Protection of Personal Information Act 4 of 2013, with encryption and secure channels for transactions. Egress from EU data centres keeps the outbound leg of each call inside Europe, one clean residency story for the customer data riding in your requests.
The gateway presents itself as PCI-DSS Level 1 certified, and every request you send already travels as signed ciphertext. A fixed, documented egress pair gives assessors a network segment they can actually describe, and TLS passthrough means the proxy only ever relays the sealed envelope.
The binding covers both fixed IPv4 addresses, so the IP restriction error stays a stranger to your logs no matter how many services, jobs, or regions originate the calls.
Email support once with the pair. Deploys, autoscaling events, and infrastructure migrations stop involving the gateway's support queue entirely.
The two addresses cover for each other inside the whitelist MustangPay already holds, so a proxy node stepping out is invisible to the payment pipeline.
New workers, services, and regions come online already behind the pair, so the binding your team arranged this month still describes every origin after a year of growth.
Your requests already travel as RSA-signed, AES-GCM-sealed envelopes. The proxy relays the TLS session without decrypting anything, on top of the encryption MustangPay requires.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
One environment variable points every MustangPay Payment API request at two fixed EU addresses the gateway already admits, from the first test preorder to the settlement checks that close the day.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
Yes, and the Payment API guide makes it mutual: each party configures an IP whitelist for API requests in its own system, requests are checked against the list, and an address that is not whitelisted earns an IP restriction error. On the gateway side the binding is performed manually after you contact their support team.
Set HTTPS_PROXY once in the environment your integration runs in. curl and Python requests pick the variable up automatically, while Node's fetch needs an explicit undici ProxyAgent. The preorder and order-status paths stay exactly as documented, and TLS passthrough keeps the encrypted envelope and its keys intact on the way through.
They never touch the proxy. The final result of an order arrives as an inbound POST to the callbackUrl you registered, your side answers with the string SUCCESS, and the confirmation call to the order-status interface is the outbound step the fixed pair covers. Whitelist MustangPay's own source addresses on your firewall so their notifications can reach you.
Happy to walk through how a managed EU proxy pair fits your rand-clearing checkout.
Contact Our Founders →