npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@piaxis/sdk

v0.2.4

Published

Official JavaScript and TypeScript SDK for the Piaxis partner API

Readme

Piaxis TypeScript SDK

Official JavaScript and TypeScript SDK for the Piaxis partner/payments API.

  • Package: @piaxis/sdk
  • npm: https://www.npmjs.com/package/@piaxis/sdk
  • Repository: https://github.com/piaxepay/typescript-sdk
  • REST API docs: https://api.gopiaxis.com/api/docs/
  • Python SDK: https://github.com/piaxepay/python-sdk

What this SDK covers

This SDK wraps the public partner/payments surface exposed at api.gopiaxis.com.

It currently covers:

  • OAuth authorize URL generation and token exchange for piaxis_external
  • OTP requests
  • Direct payments
  • Escrows and escrow actions
  • Direct disbursements
  • Escrow disbursements
  • Shared transport concerns like auth headers, timeouts, abort signals, and structured API errors

It does not attempt to wrap every backend endpoint in piaxis-api, such as internal dashboard, admin, or other non-public surfaces. A few advanced raw REST fields are also not yet promoted into the typed top-level SDK inputs. For anything outside the typed SDK surface, use the raw REST documentation at https://api.gopiaxis.com/api/docs/.

Install

npm install @piaxis/sdk

Node 18+ is required.

Choose your auth mode

Use one of these two authentication modes:

  • apiKey: merchant-owned operations like OTP, direct payments, escrows, and disbursements
  • accessToken: end-user-authorized piaxis_external payments after the OAuth flow completes

Environment variables supported by PiaxisClient.fromEnv(process.env):

  • PIAXIS_API_KEY
  • PIAXIS_ACCESS_TOKEN
  • PIAXIS_CLIENT_ID or PIAXIS_OAUTH_CLIENT_ID
  • PIAXIS_API_BASE_URL

Base URLs:

  • Sandbox: https://sandbox.api.gopiaxis.com/api
  • Production: https://api.gopiaxis.com/api

PiaxisClient.fromEnv(...) requires either PIAXIS_API_KEY or PIAXIS_ACCESS_TOKEN. The SDK rejects non-HTTPS baseUrl values unless you are explicitly targeting localhost for local tests.

export PIAXIS_API_KEY="your_sandbox_api_key"
export PIAXIS_API_BASE_URL="https://sandbox.api.gopiaxis.com/api"
import crypto from "node:crypto";
import { PiaxisClient, generatePkcePair } from "@piaxis/sdk";

const client = PiaxisClient.fromEnv(process.env);

Direct payment flow

Typical mobile-money flow:

  1. Request an OTP for the customer.
  2. Create the payment with paymentMethod: "mtn" or paymentMethod: "airtel".
  3. Poll getPayment(...) and/or consume your webhook events until the payment settles.
import { PiaxisClient } from "@piaxis/sdk";

const client = PiaxisClient.fromEnv(process.env, {
  baseUrl: process.env.PIAXIS_API_BASE_URL ?? "https://sandbox.api.gopiaxis.com/api",
});

const otp = await client.requestOtp({
  email: "[email protected]",
  phoneNumber: "+256700000000",
});

const payment = await client.createPayment({
  amount: "15000",
  currency: "UGX",
  paymentMethod: "mtn",
  userInfo: {
    email: "[email protected]",
    phone_number: "+256700000000",
    otp: process.env.PIAXIS_TEST_OTP ?? "123456",
  },
  customerPaysFees: true,
});

console.log("otp:", otp);
console.log("payment:", payment);
console.log("latest:", await client.getPayment(payment.paymentId));

Notes:

  • Top-level SDK input fields use TypeScript casing such as paymentMethod and customerPaysFees.
  • Nested payloads like userInfo, products, and terms[].data are passed through and should follow the REST API field shape.
  • Many payment methods are asynchronous. Plan for polling and webhooks instead of assuming the create call means “completed”.

OAuth and piaxis_external flow

Use this when the payer must authorize access to an external Piaxis wallet.

import { PiaxisClient } from "@piaxis/sdk";

const baseUrl =
  process.env.PIAXIS_API_BASE_URL ?? "https://sandbox.api.gopiaxis.com/api";

const authClient = new PiaxisClient({ baseUrl });
const pkce = generatePkcePair();
const oauthState = crypto.randomBytes(18).toString("hex");

const authorizeUrl = authClient.buildAuthorizeUrl({
  merchantId: process.env.PIAXIS_MERCHANT_ID!,
  externalUserId: "customer-123",
  redirectUri: process.env.PIAXIS_REDIRECT_URI!,
  state: oauthState,
  codeChallenge: pkce.codeChallenge,
  codeChallengeMethod: pkce.codeChallengeMethod,
});

console.log("redirect the customer to:", authorizeUrl);

const tokens = await authClient.exchangeToken({
  code: process.env.PIAXIS_AUTH_CODE!,
  redirectUri: process.env.PIAXIS_REDIRECT_URI!,
  clientId: process.env.PIAXIS_OAUTH_CLIENT_ID!,
  clientSecret: process.env.PIAXIS_OAUTH_CLIENT_SECRET!,
  codeVerifier: pkce.codeVerifier,
});

const payerClient = new PiaxisClient({
  accessToken: tokens.accessToken,
  baseUrl,
});

const payment = await payerClient.createPayment({
  amount: "15000",
  currency: "UGX",
  paymentMethod: "piaxis_external",
  recipientId: process.env.PIAXIS_RECIPIENT_ID,
  customerPaysFees: true,
});

console.log(payment);

If the access token expires, refresh it through the same token route:

const refreshed = await authClient.refreshToken({
  refreshToken: tokens.refreshToken,
  clientId: process.env.PIAXIS_OAUTH_CLIENT_ID!,
  clientSecret: process.env.PIAXIS_OAUTH_CLIENT_SECRET!,
});

If you want to test the authorize step without a browser redirect, use authorizeTest(...). That helper is for merchant-controlled testing only: the redirectUri must already be registered for the merchant, and the x-test-request bootstrap path is only meant for merchant owners/admins in controlled environments. redirectUri should use HTTPS in every real environment. Plain HTTP is only accepted for localhost development callbacks.

Security helpers

The SDK ships a PKCE generator and webhook verification helper:

import { generatePkcePair, verifyWebhookSignature } from "@piaxis/sdk";

const isValid = verifyWebhookSignature({
  rawBody,
  secret: process.env.PIAXIS_WEBHOOK_SECRET!,
  signature: req.headers["x-piaxis-signature"] as string | undefined,
  signatureV2: req.headers["x-piaxis-signature-v2"] as string | undefined,
  timestamp: req.headers["x-piaxis-signature-timestamp"] as string | undefined,
});

Prefer X-piaxis-Signature-V2 plus X-piaxis-Signature-Timestamp when they are present; the helper falls back to the legacy signature for older deliveries.

Escrow flow

Escrows are a separate flow from direct payments. The common lifecycle is:

  1. createEscrow(...)
  2. getEscrow(...) or getEscrowStatus(...)
  3. fulfillEscrowTerm(...), releaseEscrow(...), reverseEscrow(...), or disputeEscrow(...) depending on your business rules
import { PiaxisClient } from "@piaxis/sdk";

const client = PiaxisClient.fromEnv(process.env, {
  baseUrl: process.env.PIAXIS_API_BASE_URL ?? "https://sandbox.api.gopiaxis.com/api",
});

const escrow = await client.createEscrow({
  receiverId: process.env.PIAXIS_RECEIVER_ID!,
  amount: "50000",
  currencyCode: "UGX",
  paymentMethod: "mtn",
  externalOrderId: "order-789",
  metadata: { channel: "marketplace" },
  allocations: [
    {
      allocationKey: "seller-alpha",
      amount: "20000",
      sellerReference: "seller-001",
      description: "Alpha seller settlement",
    },
    {
      allocationKey: "seller-beta",
      amount: "30000",
      sellerReference: "seller-002",
      description: "Beta seller settlement",
    },
  ],
  userInfo: {
    email: "[email protected]",
    phone_number: "+256700000000",
    otp: process.env.PIAXIS_TEST_OTP ?? "123456",
  },
  terms: [{ type: "manual_release", data: {} }],
});

console.log(await client.getEscrowStatus(escrow.id));
console.log(
  await client.releaseEscrow(escrow.id, {
    allocationKeys: ["seller-alpha"],
    amount: "20000",
    reason: "Sandbox partial release for seller alpha",
  })
);

console.log(escrow.allocationSummary);

For marketplace checkouts, keep receiverId pointed at the merchant account and model seller or fulfillment slices with allocations. The API still escrows to the merchant; the allocation layer gives you controlled partial release and reverse behavior inside that single escrow.

Merchants should expose those allocation states and actions in the same order-management view where the buyer created the order so users can easily understand what remains held, released, or reversed.

Disbursement flows

Use direct disbursements for payouts that do not need escrow, and escrow disbursements when each payout item must satisfy terms before release.

import { PiaxisClient } from "@piaxis/sdk";

const client = PiaxisClient.fromEnv(process.env, {
  baseUrl: process.env.PIAXIS_API_BASE_URL ?? "https://sandbox.api.gopiaxis.com/api",
});

const direct = await client.disburse({
  currency: "UGX",
  paymentMethod: "airtel",
  description: "Weekly supplier payout",
  recipients: [
    {
      recipientId: "recipient-123",
      amount: "100000",
      reference: "supplier-001",
    },
  ],
});

const escrowBatch = await client.escrowDisburse({
  currency: "UGX",
  paymentMethod: "mtn",
  description: "Courier escrow batch",
  userLocation: { latitude: 0.312, longitude: 32.582 },
  recipients: [
    {
      recipientId: "recipient-123",
      amount: "100000",
      reference: "courier-001",
      terms: [{ type: "manual_release", data: {} }],
    },
  ],
});

console.log(direct);
console.log(escrowBatch);

Related methods:

  • getDisbursement(...), listDisbursements(...), cancelDisbursement(...)
  • getEscrowDisbursement(...), listEscrowDisbursements(...), releaseEscrowDisbursement(...), cancelEscrowDisbursement(...)

Error handling

API failures raise PiaxisApiError.

import { PiaxisApiError, PiaxisClient } from "@piaxis/sdk";

try {
  const client = new PiaxisClient({ apiKey: "invalid" });
  await client.listMerchantPayments();
} catch (error) {
  if (error instanceof PiaxisApiError) {
    console.log("message:", error.message);
    console.log("status:", error.status);
    console.log("code:", error.code);
    console.log("requestId:", error.requestId);
    console.log("details:", error.details);
  } else {
    throw error;
  }
}

Use requestId when talking to Piaxis support.

Request customization

You can identify your application and override request behavior:

import { PiaxisClient } from "@piaxis/sdk";

const client = new PiaxisClient({
  apiKey: process.env.PIAXIS_API_KEY,
  baseUrl: "https://sandbox.api.gopiaxis.com/api",
  timeoutMs: 60_000,
  appInfo: {
    name: "orders-service",
    version: "1.4.0",
  },
});

const payment = await client.getPayment("payment-id", {
  headers: { "x-request-id": "merchant-trace-123" },
  signal: AbortSignal.timeout(10_000),
});

This sends:

  • api-key or Authorization: Bearer ...
  • x-piaxis-sdk-client: orders-service/1.4.0 when appInfo is set
  • any extra headers you pass via requestOptions

Method map

| Capability | TypeScript method | REST endpoint | | --- | --- | --- | | Build authorize URL | buildAuthorizeUrl(...) | GET /authorize | | Test authorize redirect | authorizeTest(...) | GET /authorize with x-test-request: true (merchant-controlled testing only) | | Exchange OAuth token | exchangeToken(...) | POST /token | | Refresh OAuth token | refreshToken(...) | POST /token with grant_type=refresh_token | | Request OTP | requestOtp(...) | POST /request-otp | | Create payment | createPayment(...) | POST /payments/create | | Get payment | getPayment(...) | GET /payments/{payment_id} | | List merchant payments | listMerchantPayments(...) | GET /merchant-payments | | Create escrow | createEscrow(...) | POST /escrows/ | | Get escrow | getEscrow(...) | GET /escrows/{escrow_id} | | Get escrow status | getEscrowStatus(...) | GET /escrows/{escrow_id}/status | | Release escrow | releaseEscrow(...) | POST /escrows/{escrow_id}/release | | Fulfill escrow term | fulfillEscrowTerm(...) | POST /escrows/{escrow_id}/terms/{term_id}/fulfill | | Reverse escrow | reverseEscrow(...) | POST /escrows/{escrow_id}/reverse | | Dispute escrow | disputeEscrow(...) | POST /escrows/{escrow_id}/disputes | | Create disbursement | disburse(...) | POST /disbursements | | Get disbursement | getDisbursement(...) | GET /disbursements/{disbursement_id} | | List disbursements | listDisbursements(...) | GET /disbursements | | Cancel disbursement | cancelDisbursement(...) | POST /disbursements/{disbursement_id}/cancel | | Create escrow disbursement | escrowDisburse(...) | POST /escrow-disbursements | | Legacy alias | escrow_disburse(...) | same as POST /escrow-disbursements | | Get escrow disbursement | getEscrowDisbursement(...) | GET /escrow-disbursements/{disbursement_id} | | List escrow disbursements | listEscrowDisbursements(...) | GET /escrow-disbursements | | Release escrow disbursement | releaseEscrowDisbursement(...) | POST /escrow-disbursements/{disbursement_id}/release (force=false by default) | | Cancel escrow disbursement | cancelEscrowDisbursement(...) | POST /escrow-disbursements/{disbursement_id}/cancel |

Examples and references

  • Direct payment example: https://github.com/piaxepay/typescript-sdk/blob/main/examples/direct-payment.mjs
  • OAuth example: https://github.com/piaxepay/typescript-sdk/blob/main/examples/oauth-flow.mjs
  • Escrow example: https://github.com/piaxepay/typescript-sdk/blob/main/examples/escrow-flow.mjs
  • Disbursement example: https://github.com/piaxepay/typescript-sdk/blob/main/examples/disbursement-flow.mjs
  • Sandbox onboarding: https://github.com/piaxepay/typescript-sdk/blob/main/SANDBOX_ONBOARDING.md
  • Repository architecture: https://github.com/piaxepay/typescript-sdk/blob/main/ARCHITECTURE.md
  • REST API docs: https://api.gopiaxis.com/api/docs/