VoucherHub

VoucherHub Retailer API v1

List the products allocated to you, check your wallet balances, place orders and receive voucher codes/PINs. All amounts are decimal numbers in the stated currency. All responses are JSON.

Authentication

Create an API key in the portal under API access, then send it with every request:

Authorization: Bearer vh_live_xxxxxxxxxxxxxxxxxxxx

Base URL: https://shop.beanze.com/api/v1. Rate limit: 120 requests/minute per key. Your account may restrict calls to specific IP addresses.

Errors

HTTP 402
{ "error": { "code": "insufficient_funds", "message": "Insufficient USD balance (available 12.50)" } }

Codes: unauthorized (401), account_suspended/ip_not_allowed (403), product_not_found/order_not_found (404), invalid_quantity/invalid_reference/out_of_stock/insufficient_stock (400), insufficient_funds (402), reference_conflict (409), rate_limited (429).

GET /products

Products you can buy, with your price. Optional filters: ?currency=USD, ?brand=GameVault, ?q=search.

curl https://shop.beanze.com/api/v1/products -H "Authorization: Bearer $KEY"

{ "data": [ {
  "id": "3f0c…", "sku": "GAMEVAULT-25-USD-GLOBAL", "name": "GameVault $25 Gift Card",
  "brand": "GameVault", "category": "Gaming", "country": "Global",
  "face_value": 25, "face_currency": "USD",
  "price": 24.94, "currency": "USD",
  "in_stock": true, "stock": null,
  "image_url": null, "description": "…", "redeem_instructions": "…"
} ] }

stock: null means unlimited/unknown. GET /products/{id or sku} returns a single product.

GET /balance

{ "data": [ { "currency": "USD", "balance": 1250.00, "credit_limit": 0, "available": 1250.00 } ] }

POST /orders

Buys vouchers. Your wallet in the product's currency is debited immediately.

curl -X POST https://shop.beanze.com/api/v1/orders \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{ "product_id": "GAMEVAULT-25-USD-GLOBAL", "quantity": 2, "reference": "INV-10045" }'

HTTP 201
{ "data": {
  "id": "9b1e…", "reference": "INV-10045", "status": "completed",
  "product_id": "3f0c…", "sku": "GAMEVAULT-25-USD-GLOBAL", "product_name": "GameVault $25 Gift Card",
  "quantity": 2, "currency": "USD", "unit_price": 24.94, "total": 49.88,
  "vouchers": [ { "code": "AB12-CD34-EF56-GH78", "pin": "1234", "serial": null, "expires_at": null }, … ],
  "created_at": "…", "completed_at": "…", "error": null
}, "duplicate": false }
  • product_id — product id or SKU. quantity — 1 to 100.
  • reference — your unique order id (required). Sending the same reference again returns the original order with "duplicate": true instead of charging twice — so it's always safe to retry after a timeout.
  • status is completed (codes included), processing (supplier still working — poll GET /orders/{id} every 10–30 s or use a webhook) or failed (your wallet has been refunded automatically).

GET /orders/{id}

Order status and vouchers. Look up by your reference with GET /orders?reference=INV-10045.

GET /orders

Your latest orders (without codes). ?limit=50 (max 200), ?before=2026-10-01T00:00:00Z for paging.

GET /transactions

Wallet statement: top-ups, order debits, refunds. ?currency=USD&limit=50&before=…

{ "data": [ { "id": "…", "type": "order", "amount": -49.88, "currency": "USD", "balance_after": 1200.12,
  "order_id": "9b1e…", "reference": "INV-10045", "note": "2 × GameVault $25 Gift Card", "created_at": "…" } ] }

Webhooks

Set a webhook URL in the portal. When an order finishes we send:

POST https://your-system.example/webhooks
X-Signature: <hex HMAC-SHA256 of the raw body using your signing secret>

{ "event": "order.completed", "order": { "id": "9b1e…", "reference": "INV-10045", "status": "completed" }, "sent_at": "…" }

Events: order.completed, order.failed. Codes are not included — fetch them with GET /orders/{id}. Verify the signature, e.g. in Node.js:

const sig = crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.headers["x-signature"]))) reject();

Funding your wallet

Wallets are prepaid. Send a bank transfer and share the reference with your account manager; the balance appears in your statement as a topup once received.