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

@paychainhq/sdk

v0.1.2

Published

Official PayChainHQ TypeScript SDK for backend payment integrations.

Readme

PayChainHQ TypeScript SDK

Official PayChainHQ SDK for trusted Node.js backends. Use it to create customers and invoices, attach approved payout routes, create dynamic payout-recipient invoices with a payout key, quote and create withdrawals, verify webhooks, and read balances, transactions, networks, and tokens.

This SDK is server-side only. Never expose PayChain API keys in browsers, mobile apps, or public client code.

Install

pnpm add @paychainhq/sdk
npm install @paychainhq/sdk

Requires Node.js 18+ with native fetch.

Create a client

Use a standard business API key for invoices, customers, reads, balances, webhooks, and approved payout-route attachment.

import { PayChain } from '@paychainhq/sdk';

const paychain = new PayChain({
  apiKey: process.env.PAYCHAIN_API_KEY!,
  businessId: process.env.PAYCHAIN_BUSINESS_ID!,
  keyType: 'standard',
  environment: 'live'
});

Use a dedicated payout API key only for programmatic withdrawals and dynamic payout recipients.

const payoutClient = new PayChain({
  apiKey: process.env.PAYCHAIN_PAYOUT_API_KEY!,
  businessId: process.env.PAYCHAIN_BUSINESS_ID!,
  keyType: 'payout',
  environment: 'live'
});

Sandbox integrations must pass an explicit baseUrl:

const sandbox = new PayChain({
  apiKey: process.env.PAYCHAIN_SANDBOX_API_KEY!,
  businessId: process.env.PAYCHAIN_BUSINESS_ID!,
  keyType: 'standard',
  environment: 'sandbox',
  baseUrl: 'https://your-sandbox-api.example.com/api/v1'
});

Customers

const customer = await paychain.customers.create({
  externalRef: 'customer_123'
});

const fetched = await paychain.customers.get(customer.id);
const customers = await paychain.customers.list({ limit: 25 });

Invoices

Create an invoice with an idempotency key from your order ID.

const invoice = await paychain.invoices.create(
  {
    customerId: customer.id,
    amount: '100.00',
    token: 'USDC',
    chain: 'eth',
    networkId: 'base-mainnet',
    description: 'Order 1234'
  },
  { idempotencyKey: 'order_1234' }
);

console.log(invoice.id, invoice.depositAddress, invoice.status);

Poll an invoice when you need confirmation progress for slower-finality networks.

const invoiceStatus = await paychain.invoices.get(invoice.id);

if (invoiceStatus.confirmationProgress?.status === 'confirming') {
  console.log(
    `${invoiceStatus.confirmationProgress.current}/${invoiceStatus.confirmationProgress.required} confirmations`
  );
}

if (invoiceStatus.status === 'paid' || invoiceStatus.status === 'overpaid') {
  // Fulfill the order after verifying the webhook and fetching canonical state.
}

Attach an approved payout route template. Route templates are created and approved in the PayChain dashboard.

const invoiceWithRoute = await paychain.invoices.create(
  {
    amount: '250.00',
    token: 'USDC',
    chain: 'eth',
    networkId: 'base-mainnet',
    payoutRouteId: 'payout_route_123'
  },
  { idempotencyKey: 'order_1234_route' }
);

Use dynamic payout recipients only with a payout API key. The SDK accepts percentages and converts them to shareBps for the API.

const dynamicPayoutInvoice = await payoutClient.invoices.create(
  {
    amount: '500.00',
    token: 'USDC',
    chain: 'eth',
    networkId: 'base-mainnet',
    payoutRecipients: [
      {
        label: 'Seller',
        destinationAddress: '0x1111111111111111111111111111111111111111',
        percentage: 80
      },
      {
        label: 'Platform',
        destinationAddress: '0x2222222222222222222222222222222222222222',
        percentage: 20
      }
    ]
  },
  { idempotencyKey: 'marketplace_order_1234' }
);

The SDK rejects dynamic split totals that do not equal 100%, more than 10 recipients, and zero or negative shares before making a request.

Payout routes

Payout route templates are dashboard-managed in v1. The SDK can list and fetch active templates so your backend can attach them to invoices.

const routes = await paychain.payoutRoutes.list({ status: 'active' });
const route = await paychain.payoutRoutes.get('payout_route_123');

The SDK intentionally does not create, archive, or delete payout route templates because those actions require dashboard session auth and step-up verification.

Withdrawals

Quote withdrawals with either a standard or payout client.

const quote = await paychain.withdrawals.quote({
  amount: '25.00',
  token: 'USDC',
  chain: 'eth',
  networkId: 'base-mainnet'
});

Create withdrawals only with a payout API key.

const withdrawal = await payoutClient.withdrawals.create(
  {
    amount: '25.00',
    token: 'USDC',
    chain: 'eth',
    networkId: 'base-mainnet',
    destination: '0x3333333333333333333333333333333333333333',
    clientReference: 'payout_1234'
  },
  { idempotencyKey: 'payout_1234' }
);

Webhooks

Always verify PayChain webhook signatures using the raw request body. Do not parse JSON before verification.

import express from 'express';
import { verifyWebhookSignature } from '@paychainhq/sdk';

const app = express();

app.post('/paychain/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.header('x-paychain-signature');

  const valid = verifyWebhookSignature({
    rawBody: req.body,
    signature,
    secret: process.env.PAYCHAIN_WEBHOOK_SECRET!,
    toleranceSeconds: 300
  });

  if (!valid) {
    return res.status(400).send('invalid signature');
  }

  const event = JSON.parse(req.body.toString('utf8'));
  // Process idempotently using event.id.

  return res.sendStatus(200);
});

Webhook management helpers:

await paychain.webhooks.getConfig();
await paychain.webhooks.updateConfig({
  webhookEndpoints: [
    { label: 'Primary', url: 'https://example.com/paychain/webhook', enabled: true }
  ]
});
await paychain.webhooks.sendTest();
await paychain.webhooks.listEvents({ status: 'failed' });
await paychain.webhooks.retryEvent('webhook_event_123');
await paychain.webhooks.replayEvent('webhook_event_123');

Balances and transactions

const balances = await paychain.balances.list();
const total = await paychain.balances.total();
const byNetwork = await paychain.balances.byNetwork();
const history = await paychain.balances.history({ limit: 50, token: 'USDC' });

const tokenBalance = await paychain.balances.getTokenBalance({
  chain: 'eth',
  networkId: 'base-mainnet',
  token: 'USDC'
});

const transactions = await paychain.transactions.list({
  type: 'invoice',
  token: 'USDC',
  networkId: 'base-mainnet'
});

const summary = await paychain.transactions.summary({
  startDate: '2026-05-01',
  endDate: '2026-05-31'
});

Networks and tokens

const networks = await paychain.networks.list();
const supported = await paychain.networks.supported();

const tokens = await paychain.tokens.list({ networkId: 'base-mainnet' });
const baseTokens = await paychain.tokens.forNetwork('base-mainnet');
const usdc = await paychain.tokens.get('USDC', { networkId: 'base-mainnet' });

Idempotency and retries

Every mutating method accepts an idempotencyKey option.

await paychain.invoices.create(
  {
    amount: '100.00',
    token: 'USDC',
    chain: 'eth',
    networkId: 'base-mainnet'
  },
  { idempotencyKey: 'order_1234' }
);

The SDK retries network errors, 408, 429, and 5xx. Mutating requests are retried only when an idempotency key is present.

Errors

import {
  PayChainApiError,
  PayChainAuthError,
  PayChainRateLimitError,
  PayChainValidationError
} from '@paychainhq/sdk';

try {
  await paychain.invoices.get('invoice_123');
} catch (error) {
  if (error instanceof PayChainApiError) {
    console.log(error.status, error.code, error.requestId);
  }
  if (error instanceof PayChainValidationError) {
    console.log(error.details);
  }
}

SDK errors intentionally exclude API keys, webhook secrets, auth tokens, request headers, and raw request bodies.

Public surface

V1 includes:

  • customers.create, customers.list, customers.get
  • invoices.create, invoices.list, invoices.get
  • payoutRoutes.list, payoutRoutes.get
  • withdrawals.quote, withdrawals.create, withdrawals.list, withdrawals.get
  • webhooks.getConfig, webhooks.updateConfig, webhooks.rotateSecret, webhooks.sendTest
  • webhooks.listEvents, webhooks.retryEvent, webhooks.replayEvent, webhooks.verifySignature
  • balances.list, balances.total, balances.byNetwork, balances.byChain, balances.history, balances.getTokenBalance
  • transactions.list, transactions.summary
  • networks.list, networks.supported
  • tokens.list, tokens.forNetwork, tokens.get

V1 intentionally excludes admin APIs, dashboard session flows, step-up auth, payout route mutation, API-key management, billing mutations, internal gas sponsorship controls, provider-specific infrastructure controls, and private wallet operations.

Security checklist

  • Keep API keys on your backend.
  • Use standard API keys for collection and read workflows.
  • Use dedicated payout API keys for withdrawals and dynamic payout recipients.
  • Verify webhooks with the raw request body.
  • Do not log SDK config, API keys, webhook secrets, auth tokens, payout destination auth tokens, or raw webhook bodies.
  • Do not trust client-submitted payout destinations without your own compliance and risk checks.
  • Do not use this SDK in browsers, mobile apps, or public client code.

Documentation

Full API docs: https://paychainhq.io/docs