Node / TypeScript SDK
@xaalis/sdk is the server-side TypeScript client (Node 20+, no runtime dependencies, MIT licence).
npm install https://docs.xaalis.org/downloads/xaalis-sdk-0.1.0.tgz # `npm install @xaalis/sdk` once it is on npmEvery release, its checksums and the other packages: Downloads.
import { XaalisClient, XaalisApiError, constructEvent, formatXof } from "@xaalis/sdk";
// baseUrl defaults to https://api.xaalis.org (always HTTPS: live keys are refused over plain HTTP).// A sandbox account's keys belong to https://sandbox-api.xaalis.org — set it explicitly for those.const xaalis = new XaalisClient({ secretKey: process.env.XAALIS_SECRET_KEY!, baseUrl: process.env.XAALIS_API_URL });
const payment = await xaalis.payments.create( { amount: 15000, description: "Commande #1042", client_reference: "order_1042", success_url: "https://shop.example/merci" }, { idempotencyKey: "payment:order_1042" }, // required, and the same on every retry);console.log(formatXof(payment.amount), payment.checkout_url);| API | Methods |
|---|---|
payments |
create, retrieve, list, listAll (async iterator over every page) |
payouts |
create, retrieve, list, listAll |
payments.refunds |
create(paymentId, { idempotencyKey }), list(paymentId) — see Refunds |
subscriptions |
create, retrieve, list, listAll, cancel, testAdvance (test keys) — see Subscriptions |
invoices |
retrieve, list, listAll (filters subscription, status) |
balance |
retrieve |
agentWallets |
create, fund, reclaim, disable, keys, payouts — see Agent wallets |
testHelpers |
simulatePayment(id, "succeeded" | "failed") — test keys only |
constructEvent(raw, header, secret) |
verify and parse a webhook |
const refund = await xaalis.payments.refunds.create(payment.id, { idempotencyKey: `refund:${payment.id}` });
const sub = await xaalis.subscriptions.create( { customer: { phone: "+221771234567", name: "Awa Ndiaye" }, amount: 5_000, interval: "month" }, { idempotencyKey: "subscription:customer-123:monthly" },);// Send sub.latest_invoice?.hosted_invoice_url to the customer (it stays valid across payment attempts).What it does for you
Section titled “What it does for you”- Idempotency is explicit: every create takes an
idempotencyKeyyou choose (your order or withdrawal id) — it stays the same across retries and process restarts. - Retries only when safe: reads on network errors,
429and5xx, and any request answered429, honouringRetry-After(maxRetries, default 2). If a write’s outcome is unknown (error.outcomeUnknown), retry it yourself with the same key. - Errors:
XaalisApiError(status,code,message),XaalisNetworkError/XaalisProtocolError(outcomeUnknown),XaalisSignatureError. - Safety: refuses to run in a browser and refuses a live key over
http://.
try { await xaalis.payouts.create({ amount: 5000, provider: "wave", recipient: { phone: "+221770000001" } }, { idempotencyKey: "withdraw:2026-09-27" });} catch (err) { if (err instanceof XaalisApiError && err.code === "insufficient_funds") { /* show "balance too low" */ } else throw err;}A complete integration using it: Example shop. Full reference: packages/sdk/README.md.