SDKs
There are no official client libraries yet. The Merchant API is a small, JSON-over-HTTP API whose only non-trivial part is the HMAC request signature, so a complete client is a thin wrapper around your language's standard HTTP and crypto libraries.
Runnable examples
If you would rather start from working code, fluxa-demo has complete integrations in Node.js, Python, Go, Java, PHP, Ruby, Rust and C#. Each one signs a request, creates a charge, and receives a verified webhook. Copy .env.example, fill in three secrets, and run.
Every language there is pinned to a set of known-answer signature vectors generated from this API's own signing code, so the examples are checked against the real thing rather than against someone's reading of the docs. The repo also ships an AGENTS.md written for AI coding agents — point yours at it if you are generating the integration.
Copy the file for your language (node/src/fluxa.js, python/src/fluxa.py, go/fluxa/fluxa.go,
…) — each is standalone and dependency-light. The minimal client below is the same thing, inlined
for reading.
A minimal client
The wrapper below signs and sends any request. Build resource methods (charges.create, orders.list, …) on top of it as you need them.
Minimal client
import crypto from "node:crypto";
export class Fluxa {
constructor({ keyId, secret, baseUrl }) {
this.keyId = keyId;
this.secret = secret;
this.baseUrl = baseUrl;
}
async request(method, path, body) {
const ts = Math.floor(Date.now() / 1000).toString();
const payload = body ? JSON.stringify(body) : "";
const bodyHash = crypto.createHash("sha256").update(payload).digest("hex");
const [signPath, rawQuery = ""] = path.split("?");
// Sort by UTF-8 bytes, not with a bare .sort(): JavaScript's default compares
// UTF-16 code units, which disagrees with the server for raw code points above
// U+FFFF. Identical for ASCII/percent-encoded queries, so a naive sort passes
// every test you are likely to write and fails in production.
const byteOrder = (a, b) =>
Buffer.compare(Buffer.from(a, "utf8"), Buffer.from(b, "utf8"));
const canonicalQuery = rawQuery ? rawQuery.split("&").sort(byteOrder).join("&") : "";
const canonical = [method.toUpperCase(), signPath, canonicalQuery, ts, bodyHash].join("\n");
const signature = crypto.createHmac("sha256", this.secret).update(canonical).digest("hex");
const res = await fetch(this.baseUrl + path, {
method,
headers: {
"X-Api-Key": this.keyId,
"X-Timestamp": ts,
"X-Signature": signature,
"Content-Type": "application/json",
},
body: payload || undefined,
});
const json = await res.json();
if (!res.ok) {
throw Object.assign(new Error(json.error?.message), {
code: json.error?.code,
status: res.status,
});
}
return json;
}
// Example resource method.
createCharge(input) {
return this.request("POST", "/api/v1/charges", input);
}
}
Interactive reference
Your fluxa deployment also serves an interactive Swagger UI at /docs and the raw OpenAPI document at /openapi.yaml. The Swagger UI page can sign Merchant API requests in your browser — paste a key id and secret and it computes the X-Api-Key / X-Timestamp / X-Signature headers for each "Try it out" call.
These docs and the OpenAPI document are generated from the same backend, so the reference stays in sync with the running API.