Gift card API security rests on three layers: credentials that only your servers hold and that you can rotate without downtime, IP allowlists that limit where calls can come from, and signed webhooks you verify before acting on them. Because an API key on a funded account can buy bearer value in seconds, a leaked key is a direct financial loss, not just a data incident.
Storing the codes you receive is a separate problem, covered in storing gift card codes securely. This article is about protecting the API connection itself: who can place orders, from where, and how you know a message really came from the provider.
Why an API key here is worth more than usual
On most APIs, a stolen key leaks data. On a gift card API connected to a prepaid balance, a stolen key spends money: the attacker orders codes, receives them, and redeems them before anyone notices. There is no chargeback on a redeemed code. Every control below exists to shrink either the chance of that happening or the amount that can be lost when it does.
Authentication: keys, scopes and rotation
Providers usually authenticate with an API key or a client ID and secret exchanged for short-lived tokens. Some also sign each request with an HMAC over the request body and a timestamp. Whatever the scheme, the handling rules are the same:
- Server side only. Keys never reach a browser, a mobile app or a frontend bundle. Every order call goes through your backend.
- Secret storage. Keep keys in a secrets manager or a protected environment file, never in the repository, and never in logs or error reports.
- Separate environments. Sandbox and production keys are different, stored separately, and production keys are readable only by production services.
- Least privilege. If the provider supports scopes, give the catalogue sync a read-only key and reserve ordering rights for the order service.
- Rotation with overlap. Ask whether two keys can be active at once. That lets you issue a new key, deploy it, confirm traffic, then revoke the old one without an outage. Rotate on a schedule and immediately when someone with access leaves.
The go-live runbook covers issuing production credentials at cutover; rotation is the part teams forget to rehearse.
IP allowlists, in both directions
An IP allowlist tells the provider to accept calls with your key only from listed addresses. A stolen key used from anywhere else fails. It is one of the cheapest and most effective controls available, provided your infrastructure supports it:
- Your outbound traffic needs stable egress IPs. Serverless functions and autoscaled containers often leave from changing addresses; route provider calls through a NAT gateway or proxy with fixed IPs.
- Keep the allowlist short and documented. Every address on it is a place a stolen key would still work.
- Plan changes. Moving hosting or adding a region means updating the allowlist before the switch, or orders fail on the day of the move.
The reverse direction matters too. If the provider publishes the IPs its webhooks come from, allowlist them on your webhook endpoint. It is a useful filter, but not proof of origin on its own; that is the job of the signature.
Signed webhooks: verify before you parse
The basics of why webhooks need signatures are in webhooks vs polling for code delivery. The implementation details are where mistakes happen. A sound verifier:
- Reads the raw request body before any JSON parsing. Re-serialised JSON can differ byte for byte and the signature will not match.
- Recomputes the HMAC over the timestamp and raw body with the shared secret.
- Compares signatures in constant time.
- Rejects events whose timestamp is outside a short window, which blocks replays older than the window; dedupe by event ID for the rest.
- Only then parses the payload and processes it idempotently.
import hmac, hashlib, time
def verify(raw_body: bytes, timestamp: str, signature: str, secret: bytes) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(secret, signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
The header names and signed string format vary by provider; follow their specification exactly. And keep one rule from the webhook guide: even a valid webhook is a notification, so confirm order state through the API before releasing a code.
Controls compared
| Control | What it stops | What it does not stop |
|---|---|---|
| Server-side key storage | Keys leaking through client code | Compromise of your own servers |
| Scoped keys | A read-only leak being used to order | Theft of the ordering key itself |
| Key rotation | Old leaked keys working forever | Abuse before the leak is noticed |
| Outbound IP allowlist | Use of a stolen key from elsewhere | Attacks from inside your network |
| Webhook IP allowlist | Casual junk traffic to your endpoint | Spoofed or replayed events alone |
| Webhook signatures | Forged events and replays older than the window | Bugs in your own processing logic |
| Spend limits and alerts | Unlimited loss after a breach | The first orders of an attack |
Limit the blast radius
Assume a key will leak one day and decide in advance how much that can cost:
- Keep the prepaid balance sized to need, not to convenience; the reasoning is in sizing a prepaid deposit.
- Set per-order and daily caps in your own order service, and with the provider if they offer them.
- Alert on anomalies: order volume outside normal hours, unusual brands, a burst of failed authentications.
- Know the kill switch. Have the steps to revoke a key and freeze ordering written down and tested, with the provider’s emergency contact next to them.
Giftoro issues a sandbox key on request alongside the specification, so these controls can be built and tested before production; the gift card API overview describes the integration.
Frequently asked questions
Can I call a gift card API directly from a browser or mobile app?
No. Any key shipped to a client can be extracted and used to place orders against your balance. All calls should go through your backend, which holds the key and applies your own limits and checks before ordering.
What should I do if a gift card API key leaks?
Revoke it immediately through the provider, issue a new one, and deploy it. Then review recent orders for activity you did not initiate and report it to the provider straight away. If ordering cannot be frozen quickly, contact the provider’s support to pause the account.
Is an IP allowlist enough on its own?
No, but it is a strong second layer. It stops a stolen key from being used outside your network, while keys, rotation and spend limits handle the rest. It works best with fixed egress IPs, so plan your hosting accordingly.
Why must webhook signatures be checked against the raw body?
The signature is computed over the exact bytes the provider sent. Parsing and re-serialising JSON can change whitespace or key order, which changes the bytes and breaks verification. Verify first on the raw body, then parse.
How often should gift card API keys be rotated?
Pick a fixed schedule your team can sustain, and rotate immediately when a person with access leaves or a leak is suspected. Rotation is painless only if the provider allows two active keys at once, so ask about overlap before you sign.