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.

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.