← Stripe
Guide

How to keep Stripe keys off mobile apps and plugins with a reverse proxy

By Alastair Murdoch Last reviewed Tested on YARP 2.1 (Microsoft's reverse proxy) · .NET 8 · Stripe API
In short

Put a gateway between your apps and Stripe so the apps never hold your platform's Stripe secret key. Each app or plugin gets its own key that you can withdraw. The gateway works out which merchant it belongs to, adds the merchant's account and your fee on the server, and only passes on the Stripe requests you've approved.

4
Changes made to every request
0
Stripe secret keys on client devices
403
Refusal that blocks a merchant instantly

Before you start

  • ✓The list of Stripe features each app or plugin genuinely needs
  • ✓A way to issue and withdraw a key for each merchant
  • ✓Separate live and test platform keys, kept on the server only
  • ✓Apps and plugins whose Stripe library can be pointed at a different address

Why put a gateway in front of Stripe

Apps, plugins and partner integrations all need Stripe, but none should hold your platform's secret key or decide which merchant gets paid. A reverse proxy (a gateway that relays requests) lets them use Stripe's standard libraries while the gateway decides the account, the fee and what's allowed. We built one for Paypolli.

Only pass on what's approved

We list each Stripe request clients may make, such as creating a payment, and whether it needs the merchant's account and your fee adding. Anything else goes nowhere. The list comes from reviewing what each client actually needs.

Give each client its own key

Each merchant integration gets its own gateway key, mapped to the merchant's Stripe account, fee, fee type and live or test. Your Stripe secret stays hidden, and blocking a merchant is a straight refusal at the gateway, not a key rotation.

Change every request, in a fixed order

  1. Remove any merchant account the client named itself.
  2. Replace the client's key with your platform key, live or test.
  3. Add the merchant's account from your own records, where needed.
  4. Add your fee, the merchant and the recipient to payment requests.

A rewritten request's declared size must be updated to match, or Stripe rejects it.

Point the clients at the gateway

Most Stripe libraries can be pointed at a different address, so client code barely changes. We did the same in a modified version of WooCommerce's Stripe plugin, so every call, including Apple Pay domain registration, went through the gateway.

Webhooks come from Stripe to you, so they skip the gateway: check they're genuine at your own endpoints.

What usually goes wrong

From our own projects, not the manual.

A client could name someone else's account

Proxies pass request headers on by default, so a client could name a merchant account of its own choosing. Always remove it first, then set it from your own records, and make sure a failure to remove it blocks the request.

Rewritten requests were rejected by Stripe

After the fee was added to a request, its declared length no longer matched its content. Update the length whenever the request body changes.

Don't let the gateway leak what it protects

Logging incoming keys, or a key check that never actually rejects anything, undoes the point of the gateway. Log which key was used, never the key itself, and test that bad keys fail.

A plugin fork needed every call rerouted

Pointing a payment plugin at the gateway meant overriding its Stripe address and replacing its secret key with the platform key, including side calls such as Apple Pay domain registration.

Do it yourself, or get help?

If your developers are comfortable with ASP.NET Core and your clients' Stripe libraries can be pointed at a different address, a gateway with a handful of approved requests and changes is a few days' work. If it will carry live money for many merchants, get it reviewed: request handling and key checks are exactly where a small mistake lets one merchant act as another.

Get a developer on it
FAQ

Common questions

Can I put a publishable or secret Stripe key in a mobile app?

Never a secret key. A gateway lets the app call Stripe with its own key that you can withdraw, while your platform key and the merchant's account are added on the server.

Does a Stripe proxy break the Stripe SDKs?

No. Most Stripe libraries let you change the address they call, so client code stays standard. Only the address and the key it sends change.

Do webhooks need to go through the proxy?

No. Stripe's event notifications come straight to your own endpoints, where you check they genuinely came from Stripe.

Need your Stripe integration locked down?

Tell us which apps and partners call Stripe. We'll put a proxy in front of it and take the keys off their devices.