Gift-Card API — Code Retrieval and Automated Delivery
A gift card differs from every other digital product in one respect: the code is irreversible. Once that string reaches a buyer you have no way of knowing whether it has been redeemed, and every dispute is settled by your log rather than by common sense. Below is the full path of a code from order to delivery, focused on the places where money is actually lost.
Five stages you must keep separate
Most code-issuance bugs happen because a developer treats all of this as one operation. It is five operations with five different failure modes:
| Stage | What happens | Who owns the state |
|---|---|---|
| 1. Order | You submit a purchase request | Your DB + supplier |
| 2. Issuance | Supplier reserves and issues a code | Supplier |
| 3. Retrieval | You pull the code out of the response | Your DB |
| 4. Storage | Code sits encrypted on your side | Your DB |
| 5. Delivery | Buyer sees the code | Your frontend / email |
Every transition should be its own timestamped row in your database. If you have one status column covering the whole journey, the first failure leaves you unable to answer the only question that matters: was a code issued at all?
Stage 1. Placing the order
An order is created with a product ID and quantity:
curl -X POST "https://public-api.foxreload.com/api/orders" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"itemId": "product_01krgfgww8eth9xvvysd6y7r4j",
"quantity": 1
}
],
"isMock": false
}'
The response is an order object with status active, plus id, price, createdAt, paymentExpiresAt and an items[] array.
Three rules at this stage:
- Record the intent in your database before calling the supplier, not after. A row saying "we are about to order this for customer X" must exist before the HTTP request leaves — otherwise a process crash between send and response leaves no trace at all.
- Persist the supplier's
order_idthe moment it arrives. It is the only key by which you will ever find that order again. - Never mix mock and production orders in one table without an explicit flag. FoxReload's order object carries
isMock— copy it into your own schema.
Stage 2. Issuance on the supplier's side
After creation the order moves active → paid (balance debited) → processing (supplier issuing) → completed.
The processing phase belongs to someone else's system and can last from seconds to noticeably longer depending on card type. Your only job here is to do nothing destructive while the state is unknown. No "it probably failed, let's order another one."
Stage 3. Retrieving the code
The code is retrieved by polling the order:
curl "https://public-api.foxreload.com/api/orders/{order_id}" \
-H "X-API-Key: YOUR_API_KEY"
When status == "completed", each items[] entry carries:
product— the product object withid,name,userGuide,attributesexternalData[]— the array of issued codes or PINserror— a per-item error, if there is one
The userGuide field is not decorative. It is the supplier's activation instruction and it should reach the buyer alongside the code — half of all "the code doesn't work" tickets actually mean the buyer is redeeming it in the wrong region or the wrong part of their account.
About webhooks — check your own supplier
Some suppliers can notify you when an order completes, often with an HMAC signature on the callback. Verify whether your specific supplier implements this. FoxReload does not support webhooks — results are retrieved by polling only.
Even where webhooks exist, keep polling as the safety net: delivery is never guaranteed and your handler may be down at exactly the wrong moment. The webhook is an accelerator; polling is the source of truth.
Partial fulfilment
On a multi-line order, items complete independently. One line can return a code while another fails with a populated items[].error.
The correct response:
- Whatever was genuinely issued gets stored and delivered. That money is already spent and the code exists.
- For the missing part, either re-order as a separate operation or refund the customer.
- Never mark the whole order failed once some codes have gone out. That path ends in refunding goods the customer already received.
Stage 4. Duplicate-issuance protection
This is the most expensive mistake in the category, and it arises in two different places.
Duplicates at the order level
You send an order-creation request, get a timeout, retry — and create two orders. You have now bought two codes, delivered one, and the second either sits dead on your books or, worse, goes out to the next buyer by accident.
Some APIs accept an Idempotency-Key header that solves this on the supplier's side. Verify whether your supplier actually implements it — many do not. FoxReload does not support an Idempotency-Key header.
So the protection lives with you:
- Persist a unique operation key in your database before the call.
- On a timeout, query the supplier's order list first, filtered by status, and check whether the order exists.
- Only retry once you have confirmed it does not.
curl "https://public-api.foxreload.com/api/orders/?statuses=active,processing&limit=20" \
-H "X-API-Key: YOUR_API_KEY"
Duplicates at the delivery level
The second source is a race inside your own system. A customer clicks "get my code" twice, two concurrent requests both read the order row as "code ready, not delivered", and both proceed to deliver.
Fix it with a transaction and a row lock: delivery marks the order as delivered and commits before the code leaves your system. If the code goes out by email, the send is enqueued inside that same transaction rather than performed synchronously in the middle of it.
Retries
The general rule: only retry what is safe to repeat.
429and5xx— retry with exponential backoff and jitter.4xxother than429— never retry, the answer will not change.- A timeout on order creation — not a retry, a state check first.
More detail in the retry and backoff patterns article.
Stage 5. Storage — encryption and access
A gift-card code is a bearer instrument. Whoever reads it can spend it.
- Encrypt the code value at the application layer with a key from your secret manager. Disk encryption is not enough: a database dump, a stolen backup or an SQL injection all read the disk already decrypted.
- Restrict decryption to one service. Your analytics replica, your support admin panel and your debugging scripts should not hold the decryption right.
- Never write codes to logs. Not to standard logs, not to debug output, not to APM traces, not into the body of a support ticket. Mask the value on the way out of your data-access layer rather than at every individual print site.
- Store a hash alongside the code. It lets you prove "this is the code we issued" without exposing the value a second time.
- Set a retention period. Once delivered and past the dispute window, the encrypted value can be deleted while the hash and metadata remain.
Stage 6. Delivery and the audit trail
Delivery is itself an operation that can fail. Email bounces, tabs close, buyers mistype their address.
A working pattern:
- The code is displayed once, on a protected order page available only to the authenticated buyer.
- Re-access happens through the account area, with every view written to a log.
- Any one-time view link is short-lived and single-use.
- The first display is recorded with a timestamp — that is the fact you will cite in a dispute.
The audit trail
The minimum set of events to record per code:
| Event | What you capture |
|---|---|
| Order created | Internal ID, product, buyer, timestamp |
| Supplier ID received | The supplier's order_id |
| Code retrieved | Code hash, line item, timestamp |
| Code shown to buyer | Timestamp, IP, session identifier |
| Dispute opened | Link to order and ticket |
| Dispute resolved | Refund, denial, replacement |
This log — not a support thread — is what answers "was the code delivered, and when". How that evidence plays out in practice is covered in avoiding chargebacks on digital goods.
Keep in mind the risks no amount of code can fix: issuer-side revocation, regional redemption restrictions, and cards voided when the issuer suspects fraud. Those scenarios are broken down in handling code revocation and region locks.
Where to source gift cards wholesale
The pipeline above is worth building once, against a catalogue wide enough to cover your whole range. FoxReload is a wholesale digital-goods supplier with 900+ SKUs — gift cards, game keys, top-ups, eSIM and software licences — all behind one REST API with automated delivery and multi-region SKUs. One order model and one response shape across every category, instead of a separate integration per issuer.
