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

paisr-js

v0.3.1

Published

Typed JavaScript/TypeScript client for the Paisr API

Readme

paisr-js

A typed JavaScript/TypeScript client for the Paisr API — wallets, transfers, customers, vouchers, plans, invoices, subscriptions, payments, provider connections, webhooks, and access tokens.

Built on axios with types generated from Paisr's OpenAPI spec via openapi-typescript. Works in Node.js 18+ and in the browser.

Install

npm install paisr-js

Usage

import { Paisr } from "paisr-js";

const paisr = new Paisr({
  apiKey: process.env.PAISR_API_KEY!,
  environment: "live", // or "staging" (defaults to "live")
});

// List wallets
const { wallets } = await paisr.wallets.list();

// Create a wallet
const created = await paisr.wallets.create({
  type: "business",
  currency: "USD",
});

// Nested wallet resources
const balances = await paisr.wallets.balances.list(created.id);
const transactions = await paisr.wallets.transactions.list(created.id, { limit: 25 });
await paisr.wallets.pin.rotate(created.id);

// Customers, invoices, subscriptions, payments...
const customer = await paisr.customers.add({ email: "[email protected]" });
const invoice = await paisr.invoices.create({ customer_id: customer.id });
await paisr.invoices.send(invoice.id);

const payment = await paisr.payments.initiate("card", {
  amount: 5000,
  currency: "USD",
});

Error handling

Every non-2xx response throws a PaisrError with the HTTP status and parsed response body attached:

import { Paisr, PaisrError } from "paisr-js";

try {
  await paisr.wallets.get("does-not-exist");
} catch (err) {
  if (err instanceof PaisrError) {
    console.error(err.status, err.message, err.body);
  }
}

Custom base URL / axios instance

const paisr = new Paisr({
  apiKey: "...",
  baseUrl: "https://api.staging.paisr.tech/v2", // overrides `environment`
  axiosInstance: myAxiosInstance, // e.g. for retries, proxying, or testing
});

baseUrl must be https:// — a non-https:// value throws unless you pass allowInsecureBaseUrl: true (e.g. for local proxying against a plain-HTTP dev server).

Per-request headers (e.g. idempotency keys)

Every client method accepts a headers option, forwarded as-is on that request:

await paisr.payments.initiate(
  "wallet",
  { invoice_id, ... },
  { headers: { "Idempotency-Key": crypto.randomUUID() } },
);

Use this to attach an idempotency key on retried payment/transfer-creating calls, if the target Paisr environment supports one.

Verifying webhook signatures

Paisr signs each webhook delivery with an X-PCB-Signature header (HMAC-SHA256 over ${X-PCB-Timestamp}.${rawBody}, keyed with the webhook's signing secret — see paisr.webhooks.getSecret()). Use constructWebhookEvent to verify and parse a delivery in one step:

import { constructWebhookEvent } from "paisr-js";

// e.g. inside an Express/Fastify/Hono handler — verify against the *raw* request body,
// not a re-serialized parsed object, or the signature check will fail.
const event = await constructWebhookEvent({
  payload: rawBody, // string
  signature: req.header("X-PCB-Signature")!,
  timestamp: req.header("X-PCB-Timestamp")!,
  secret: process.env.PAISR_WEBHOOK_SECRET!,
});

Or call verifyWebhookSignature({ payload, signature, timestamp, secret }) directly if you just need a boolean.

By default, deliveries older than 5 minutes are rejected as expired/replayed webhooks. Pass toleranceSeconds: 0 to disable this check, or a different value to widen/narrow the window.

Security notes

  • Raw card data (payments.initiate("card", ...)): this method requires a raw card number and CVV/CVC in card_details. Collecting and forwarding that data yourself puts your own systems in full PCI DSS scope (SAQ D). Prefer a hosted/tokenized card entry flow if Paisr offers one.
  • Webhook replay protection: verifyWebhookSignature/constructWebhookEvent reject deliveries whose X-PCB-Timestamp is more than 5 minutes old by default — see above to adjust.
  • Transport security: if you override baseUrl with a non-https:// URL, the SDK logs a warning, since your API key and any payment data would otherwise be sent unencrypted.
  • Timeouts: the default axios instance uses a 30s request timeout; pass your own axiosInstance to customize.

Resources

| Namespace | Covers | | --- | --- | | paisr.accessTokens | Access tokens & their permissions | | paisr.webhooks | Webhooks, secrets, triggers, delivery events | | paisr.wallets | Wallets, plus nested .pin, .statements, .transactions, .balances, .accounts, .contacts, .links | | paisr.transfers | Initiate/approve/cancel transfers, batch transfers | | paisr.customers | Customers | | paisr.vouchers | Vouchers, applying voucher codes | | paisr.plans | Plans, plus nested .options (price options) | | paisr.invoices | Invoices, plus nested .line_items | | paisr.subscriptions | Subscriptions, restore/cancel | | paisr.payments | Payments, refunds | | paisr.providers | Provider connections | | paisr.metrics | Invoice/subscription/payment/customer metrics | | paisr.logs | API request logs |

All request/response types are generated directly from Paisr's OpenAPI spec (vendored at src/spec/paisr.yaml), so method signatures stay in sync with the API surface.

Development

npm install
npm run generate   # regenerate src/generated/types.ts from src/spec/paisr.yaml
npm run typecheck
npm run build       # outputs ESM + CJS + .d.ts to dist/

To pick up API changes, replace src/spec/paisr.yaml with the latest spec and re-run npm run generate.