Security best practices
The controls PayDirect gives you, how to combine them, and what to do when a credential leaks.
Your API credentials can move money. Treat them like the keys to a bank account, because that is what they are. This page collects in one place the controls described across these guides.
Keep credentials on your server
- Sign on the server, only. Never ship the raw API key or the secret key to a browser, a mobile app or any device you do not control. A key in client code is public the moment it ships.
- Use a secret manager, not
.envfiles committed anywhere, and not configuration baked into images. - Never log credentials, not even truncated. Log the public key (
pk_…) if you need to know which key was used. - One key per service and per environment, so a compromise is contained and can be revoked in isolation. See API keys.
Give each key only what it needs
A key's scopes decide what it can do. Ask PayDirect to narrow a key when a service needs less than
the full set. For example, a service that only collects and settles to your own account should
hold COLLECTIONS_WRITE and WITHDRAWALS_WRITE, and not PAYOUTS_WRITE. Then a leaked key
cannot send your balance to a stranger's wallet: a withdrawal can only ever reach the settlement
account PayDirect registered for you.
A narrowed key also cannot change your Integrator's configuration - keys, webhook and callback URLs, or the IP allowlist - so it cannot widen its own access. See Narrowed keys cannot manage configuration.
Restrict where keys work
Add your servers' public egress addresses to the IP allowlist for LIVE. A stolen key then fails from anywhere else, and the refused attempts show up in your usage events.
Verify every webhook
- Verify the
X-UmoPay-SignatureHMAC against the raw request body, with a timestamp tolerance and a constant-time comparison. - Reject unsigned deliveries outright.
- Branch on
environment, so a TEST event can never be processed as a real payment. - Dedupe on
eventId.
See Verifying signatures.
Never trust the browser for payment status
A hosted checkout redirect, or anything else that arrives through the payer's browser, is a URL
anyone can visit. Confirm the outcome server-to-server - from the webhook, or
GET /checkout/check-status/{id} - before you ship anything. See
Hosted checkout.
Watch for misuse
- Review
GET /integrators/{id}/usage/summaryregularly. A spike inBAD_SIGNATUREorIP_NOT_ALLOWEDoutcomes suggests someone may be trying your credentials. It is not proof: a misconfigured client, a clock-skew problem or an unlisted server IP can look the same, so investigate the source of the failures before drawing a conclusion, and rotate your keys if the investigation confirms misuse. - Rotate keys on a schedule, and immediately on any suspicion.
- Remove team members who no longer need access.
When a credential leaks
A key that appeared in a log, a screenshot, a support ticket or a repository is compromised, whether or not anyone used it.
- Issue a replacement and deploy it.
- Revoke the leaked key with
PATCH /apikey/revoke-my-key/{id}. You do not need to wait for us. - Check what it did. Pull
GET /apikey/{id}/usage/eventsfor the key, and review transactions over the same window. - Tell us, with Security at the start of the subject line. See Support.
For a leaked webhook signing secret, contact support to have it replaced. See Rotating the secret.
Reporting a vulnerability
If you find a security weakness in PayDirect, report it to support@softmastersgroup.com with Security at the start of the subject line. Include enough detail to reproduce it. Do not access other customers' data, degrade the service, or move real money while investigating.
Next
Support - how to reach us.