🇪🇺 Whitelist-ready egress for MustangPay

Static IP for MustangPay

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.

checkout-service · shell

# 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

A front door operated by hand

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.

Bound by support ticket, not a dashboard

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.

The check runs in both directions

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.

Async keeps your egress in the loop

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.

The envelope shows the edge one thing: your IP

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.

The Solution

Ask support to bind two fixed EU IPs once, then forget the front door

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.

Declare 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.
Both addresses are bound from the first day. Either can carry the traffic on its own, so a failover between nodes never sends anyone back to support for a fresh binding.
TLS runs straight through to MustangPay. Your RSA keys, the random aesKey, and the encrypted payload stay sealed past the proxy hop, and the gateway receives exactly what your code signed.

Why payment teams route MustangPay through OutboundGateway

One request, then done

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.

A rhythm that never ages 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.

Ciphertext all the way down

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.

Designed for

Teams whose MustangPay traffic has to arrive recognized, on every call the integration makes.

Platforms selling into South Africa

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.

Cashier-flow integrators

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.

Reconciliation schedulers

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.

Autoscaling infrastructure

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.

Implementation

One environment variable routes every encrypted MustangPay envelope out of your fixed EU address.

Shell / environment

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

Python (requests)

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.js (undici ProxyAgent)

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

Run the binding ceremony once

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.

Johannesburg gateway, European egress

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.

POPIA-aligned data journeys

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.

PCI posture, sealed envelopes

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.

What you get

Two entries, forever

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.

One ticket, not a habit

Email support once with the pair. Deploys, autoscaling events, and infrastructure migrations stop involving the gateway's support queue entirely.

Failover without a re-binding

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.

Scale rewrites nothing

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.

Ciphertext stays ciphertext

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.

Simple pricing

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

Bind the pair once, call forever after

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.

Frequently asked questions

Does MustangPay support IP whitelisting?

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.

How do I route MustangPay API traffic through the proxy?

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.

What about MustangPay notifications to my callbackUrl?

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.

A front door MustangPay already recognizes

Happy to walk through how a managed EU proxy pair fits your rand-clearing checkout.

Contact Our Founders →