Inventory
BD Voucher tracks inventory along two independent dimensions and exposes both to the client API so you can render accurate availability badges without polling a separate endpoint.
The two inventory tracks
| Track | Used by | What it measures |
|---|---|---|
| PRELOADED | Products fulfilled from a pre-loaded voucher pool | Count of voucher rows in available status |
| API + cap | Products fulfilled by an upstream partner API call | Soft stock_cap — manually-throttled daily limit |
A variant uses the PRELOADED track when its winning partner source has
fulfillment_type = 'PRELOADED', otherwise it uses the API track. You
don’t need to know which — the response shape is identical.
Stock envelope on the variant
Every variant in the products endpoint includes a stock object:
{ "variant_id": 22402, "name": "USD 10 Steam Wallet", "price": 1100, "stock": { "in_stock": true, "status": "in_stock", "level": 47, "low_stock": false, "low_stock_threshold": 5, "source": "preloaded" }}Field meanings
| Field | Type | Meaning |
|---|---|---|
in_stock | boolean | true when the variant can be ordered right now. |
status | string | One of in_stock, low_stock, out_of_stock, unlimited, untracked. |
level | number | null | Available units right now. null for unlimited / untracked. |
low_stock | boolean | true when level is at or below low_stock_threshold. |
low_stock_threshold | number | null | At or below this number status flips to low_stock. null when not configured. |
source | string | Inventory track: preloaded, api, or untracked. |
Recommended UI mapping
status value | Badge text | Behaviour |
|---|---|---|
in_stock | (no badge) | Standard “Buy” CTA. |
low_stock | ”Only N left!” | Show level count to drive urgency. |
out_of_stock | ”Out of stock” | Disable “Buy” CTA, optionally show “Notify me” form. |
unlimited | (no badge) | Standard “Buy” CTA. |
untracked | (no badge) | Standard “Buy” CTA. |
What changes during checkout
When the customer places the order:
- The platform locks N voucher rows for PRELOADED variants (atomic, race-safe).
- For API-track variants the platform decrements the soft
stock_capcounter. - If reservation fails (raced to zero) the whole order rolls back with
409. - Successful payment → reservations confirmed →
levelcount drops on next page-load. - Failed/cancelled order → reservations released →
levelcount restored.
You don’t need to subscribe to anything to see updated counts — just re-fetch the product when the user returns from the payment redirect, or after a checkout error.
Caching guidance
The stock envelope is computed at request time from the latest
inventory rows. It is safe to cache the rest of the variant payload
indefinitely; cache stock for at most 30 seconds on edge / CDN layers.
For more accuracy on the product detail page, fetch with cache: no-store.