fazercards
v0.1.0
Published
Official Node.js / TypeScript SDK for the FazerCards reseller API — gift cards, game top-ups, subscriptions through one REST API.
Maintainers
Readme
fazercards
Official Node.js / TypeScript SDK for the FazerCards reseller API — sell gift cards, mobile game top-ups, subscriptions and game keys through a single REST contract with instant automated delivery.
- 10 000+ SKUs in 1 000+ categories (Amazon, Steam, PSN, Xbox, Google Play, iTunes, Nintendo, Roblox, PUBG Mobile UC, Free Fire, Mobile Legends, Genshin, Valorant, ...)
- Webhooks for asynchronous order fulfilment (
order.completed/order.failed/order.refunded) - Crypto-native top-up — Binance Pay + USDT on TRC20 / BEP20 / TON / Aptos
- B2B-only, 5-day free Gold trial, no card
Full reference: https://reseller.fazercards.com/en/docs · Cookbook recipes: https://reseller.fazercards.com/en/docs/cookbook
Install
npm install fazercards
# or
pnpm add fazercards
# or
yarn add fazercardsRequires Node.js 18 or newer (uses built-in fetch and AbortSignal).
Quick start
import { FazerCardsClient } from "fazercards";
const fz = new FazerCardsClient({
apiKey: process.env.FAZER_API_KEY!,
});
// 1. Browse the catalog
const page = await fz.catalog.list({ category: "gift-cards", limit: 50 });
for (const sku of page.items) {
console.log(sku.id, sku.name, sku.priceUsd, "USD");
}
// 2. Place an order (Amazon $10 gift card, US storefront)
const order = await fz.orders.create({
sku_id: "amazon-us-10",
quantity: 1,
idempotencyKey: "auto", // generates a UUID and reuses it across retries
});
// 3. Read the code / poll status
const result = await fz.orders.get(order.id);
console.log(result.status, result.code);The SDK handles authentication (X-Api-Key header), JSON encoding, request timeouts, automatic retries on HTTP 429 + 5xx with Retry-After-aware backoff, and typed error classes.
Get an API key from the reseller panel — the 5-day Gold trial is free and requires no card.
Webhooks
The recommended fulfilment pattern is webhooks, not polling. Register your HTTPS endpoint in the reseller panel under Settings → Webhooks, then verify every payload:
import express from "express";
import { parseWebhookEvent } from "fazercards";
const app = express();
app.post(
"/webhooks/fazercards",
express.raw({ type: "application/json" }),
(req, res) => {
try {
const event = parseWebhookEvent(
req.body,
req.header("x-fazercards-signature") ?? "",
process.env.FAZER_WEBHOOK_SECRET!
);
switch (event.type) {
case "order.completed":
deliverToCustomer(event.order);
break;
case "order.failed":
notifyFailure(event.order, event.reason);
break;
case "order.refunded":
refundCustomer(event.order);
break;
}
res.sendStatus(200);
} catch {
res.status(401).send("bad signature");
}
}
);Signatures are HMAC-SHA256 of the raw body, hex-encoded in the X-FazerCards-Signature header — comparison is timing-safe.
Idempotency
POST /order and POST /payments are idempotent when you send the Idempotency-Key header. The SDK accepts three forms:
// 1. Explicit value — generate once on your side, reuse across retries of the SAME logical order.
await fz.orders.create({ sku_id: "amazon-us-10", idempotencyKey: "order-2026-05-25-abc123" });
// 2. "auto" — SDK generates a UUID v4 per call (good for one-shot scripts).
await fz.orders.create({ sku_id: "amazon-us-10", idempotencyKey: "auto" });
// 3. Omitted — no key sent. Avoid in production; risks duplicate orders on network retries.
await fz.orders.create({ sku_id: "amazon-us-10" });Rate limits
The public API uses per-category sliding windows so polling order status can't starve order creation (and vice versa). Defaults:
| Category | Limit |
|---|---|
| Catalog read (GET /catalog, /prices, /skus) | 30 / min |
| Order create (POST /order, /topup, /gift-cards, ...) | 60 / min |
| Order status (GET /order/{id} polling) | 120 / min |
| Account read (GET /me, /balance, /subscription) | 30 / min |
| Payment write (POST /payments) | 15 / min |
| Default (everything else) | 120 / min |
| Login | 10 attempts / 15 minutes per IP |
Counter key is (category × API key) — categories don't share budget. On overshoot the SDK auto-retries with Retry-After-aware backoff and ±15 % jitter. See the rate-limit cookbook recipe for the underlying pattern.
Pagination
catalog.list() returns a single page with next_cursor. To walk every SKU in a category:
for await (const sku of fz.catalog.listAll({ category: "gift-cards" })) {
process(sku);
}Internally this loops over list({ ..., cursor }) until next_cursor is empty.
Errors
All SDK errors derive from FazerCardsError:
import {
FazerCardsError,
FazerCardsAuthError,
FazerCardsNotFoundError,
FazerCardsRateLimitError,
FazerCardsServerError,
} from "fazercards";
try {
await fz.orders.create({ sku_id: "amazon-us-10" });
} catch (err) {
if (err instanceof FazerCardsAuthError) {
// Rotate / replace the API key.
} else if (err instanceof FazerCardsRateLimitError) {
console.log("Throttle for", err.retryAfterSeconds, "s");
} else if (err instanceof FazerCardsServerError) {
// The SDK already auto-retried up to `retries`; surface to ops.
} else if (err instanceof FazerCardsError) {
console.log("API error", err.status, err.code, err.message);
} else {
throw err;
}
}Client options
new FazerCardsClient({
apiKey: process.env.FAZER_API_KEY!,
baseUrl: "https://api.fazercards.com/api/v2", // default
timeoutMs: 30_000,
retries: 3, // retries on 429 / 5xx / network errors (0 = disable)
appName: "my-bot/1.4", // prepended to the User-Agent header
fetch: globalThis.fetch, // override for tests or custom transports
});More
- API documentation: https://reseller.fazercards.com/en/docs
- Cookbook (curl / Node / Python / Go recipes): https://reseller.fazercards.com/en/docs/cookbook
- Webhooks guide: https://reseller.fazercards.com/en/docs/webhooks
- Glossary: https://reseller.fazercards.com/en/glossary
- Free trial: https://reseller.fazercards.com/en/free-trial
- Telegram channel: https://t.me/FazerCardsReseller
License
MIT © FazerCards.
