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

@zkp2p/pay-sdk

v7.0.0

Published

ZKP2P Pay checkout SDK

Readme

@zkp2p/pay-sdk

TypeScript SDK for creating checkout orders against the canonical orders API and creating and managing payouts.

  • Package: @zkp2p/pay-sdk
  • Runtime: Node.js with fetch for authenticated calls; browser helpers for navigation and embedding
  • Module format: ESM

Install

npm install @zkp2p/[email protected]

Published artifacts

  • Includes compiled ESM JavaScript and .d.ts type declarations.
  • Does not publish declaration maps (.d.ts.map) or JavaScript source maps (.js.map).

Recommended flow

Create checkout on your backend and return checkout.checkoutUrl to the browser. Never bundle the merchant API key into a frontend. The redirect helper below runs separately in the browser with public URL options only.

import {
  createCheckout,
  redirectToCheckout,
  type CheckoutClientOptions,
} from '@zkp2p/pay-sdk';

const client: CheckoutClientOptions = {
  apiBaseUrl: 'https://api.pay.peer.xyz',
  checkoutBaseUrl: 'https://pay.peer.xyz',
  apiKey: '<merchant-api-key>',
};

const checkout = await createCheckout(
  {
    requestedFiatAmount: '25.00',
    requestedFiatCurrency: 'EUR',
    destinationAddress: '0xYourRecipientAddress',
    destinationToken: 'USDC',
    destinationChainId: 8453,
    successUrl: 'https://merchant.example/success',
    cancelUrl: 'https://merchant.example/cancel',
    notes: { cartId: 'cart_123' },
  },
  client,
);

// Browser code, after receiving orderId and orderToken from your backend:
redirectToCheckout(orderId, orderToken, {
  apiBaseUrl: 'https://api.pay.peer.xyz',
  checkoutBaseUrl: 'https://pay.peer.xyz',
});

Functions

createCheckout(params, options)

Creates an order via POST /api/v1/orders and returns:

  • order
  • orderToken
  • checkoutUrl

params maps to the API schema:

  • amount input XOR:
    • requestedUsdcAmount
    • requestedFiatAmount + requestedFiatCurrency
    • openAmount: { currency, minAmount?, maxAmount?, presets? } (the buyer chooses the amount at checkout)
  • idempotencyKey (optional, see below)
  • destinationAddress (optional)
  • destinationToken (optional)
  • destinationChainId (optional)
  • feePayer (optional): MERCHANT, PAYEE, or SPLIT
  • buyerFeeShareBps: required with explicit SPLIT; buyer share of total fees in basis points (5000 = 50%, 0–10000 in steps of 1000)
  • dynamicOrdersEnabled (optional; inherits merchant configuration when omitted)
  • enabledRails (optional)
  • successUrl (nullable, defaults to null)
  • cancelUrl (nullable, defaults to null)
  • notes (nullable, defaults to null)

In fiat mode, the API converts to canonical USD/USDC amounts and persists order amounts in USDC fields.

Idempotent order creation

Pass idempotencyKey in params to reuse an order on retries. Use one stable key per purchase, including after a timeout: 8–128 letters, digits, underscores or hyphens. The API compares amount and mode; changing either returns 409 IDEMPOTENCY_KEY_CONFLICT. Other fields do not update the original order.

On replay, the API returns idempotentReplay: true and orderToken: null. The SDK returns checkoutUrl: null and preserves the replay marker. Save the first checkout URL on your backend; a replay does not recover a lost token or create a new checkout link. createCheckoutAndRedirect returns a replay without navigating. Handle the nullable URL before redirecting.

getCheckoutUrl(orderId, orderToken, options)

Builds the checkout URL using checkoutBaseUrl when provided and apiBaseUrl otherwise.

redirectToCheckout(orderId, orderToken, options)

Browser helper that redirects to the checkout URL.

createCheckoutAndRedirect(params, options)

Creates an order and immediately redirects.

getMerchant(options)

Fetches merchant profile data via GET /api/v1/merchants/me. The merchant is determined by the API key in options — there is no merchant-id parameter.

checkQuoteAvailability(params, options)

Checks whether quotes exist for an amount before you create an order, and returns nearby amounts that would fill when they do not. Calls POST /api/v1/merchants/me/quotes/availability.

Server-side only. This sends your merchant API key. Never call it from browser code.

nearbySuggestions is null whenever available is true, and available: true is advisory — the API reserves no liquidity, so order creation can still fail.

Pass the same enabledRails override as createCheckout to check the customer's selected payment method. When omitted, any serviceable merchant rail can make available true, even if a different rail selected for checkout is unavailable. Forwarding enabledRails requires SDK 4.0.1 or later and an API deployment that supports rail-scoped availability. Earlier SDK versions omit the field from the request. Upgrade the package and redeploy your backend before relying on it.

import { checkQuoteAvailability, CheckoutMode } from '@zkp2p/pay-sdk';

const availability = await checkQuoteAvailability(
  {
    amount: '25.00',
    quoteMode: CheckoutMode.EXACT_TOKEN,
    enabledRails: ['venmo'],
    destinationChainId: 8453,
    destinationToken: 'USDC',
    destinationAddress: '0xYourPayoutWallet',
  },
  { apiBaseUrl, apiKey, signal: AbortSignal.timeout(8_000) },
);

See the Quote Availability guide for the full field reference.

Payouts

Server-side only. Every payout call sends your merchant API key. Never call it from browser code.

  • createPayout(params, { idempotencyKey }, options) — POST /api/v1/payouts; returns a PayoutView with checkoutUrl and idempotentReplay.
  • getPayout(payoutId, options) — GET /api/v1/payouts/:id; returns a PayoutView.
  • listPayouts(params, options) — GET /api/v1/payouts; accepts optional customerEmail, status, merchantReference, page and limit, and returns items, page, limit and total, newest first.
  • cancelPayout(payoutId, options) — POST /api/v1/payouts/:id/cancel; cancels a payout awaiting funding that has received nothing and returns its PayoutView.

idempotencyKey is required: 8–128 letters, digits, _ or -, checked before sending. Use one stable key per withdrawal. A retry with the same key and body returns the same payout with idempotentReplay: true and its current checkoutUrl.

See the Payouts guide for funding, filters, cancellation rules and errors.

Legacy APIs

Legacy session helper APIs are not exported from the current SDK surface.

Client options

type CheckoutClientOptions = {
  apiBaseUrl: string;
  checkoutBaseUrl?: string;
  apiKey?: string;
  fetcher?: typeof fetch;
  signal?: AbortSignal;
};

Payout calls take PayoutClientOptions:

type PayoutClientOptions = {
  apiBaseUrl: string;
  apiKey: string;
  fetcher?: typeof fetch;
  signal?: AbortSignal;
};

Payout webhooks

WebhookPayload is a union of OrderWebhookPayload and PayoutWebhookPayload. After verifying the webhook signature, narrow with isPayoutWebhook before reading data:

import { PAYOUT_WEBHOOK_VERSION, isPayoutWebhook, type WebhookPayload } from '@zkp2p/pay-sdk';

function handleWebhook(payload: WebhookPayload) {
  if (isPayoutWebhook(payload)) {
    // payload.data is PayoutView; payload.version is PAYOUT_WEBHOOK_VERSION (2).
    console.log(payload.data.payoutId, payload.data.status, PAYOUT_WEBHOOK_VERSION);
  } else {
    console.log(payload.data.order, payload.data.payment);
  }
}

Embedded checkout helpers

import {
  EMBED_EVENT_CHANNEL,
  isEmbeddedCheckout,
  ensureEmbedModeUrl,
  buildEmbedCheckoutEvent,
  postEmbedCheckoutEvent,
} from '@zkp2p/pay-sdk/embedded';

Mount checkout with ensureEmbedModeUrl, and if you sandbox the iframe include allow-popups and allow-popups-to-escape-sandbox:

<iframe
  title="Embedded Checkout"
  src={ensureEmbedModeUrl(checkoutUrl)}
  sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"
/>

Embedded checkout opens payment apps in a new tab, because providers including Cash App and PayPal serve X-Frame-Options: SAMEORIGIN and cannot load in-frame. Without allow-popups the browser silently drops the Pay with … click and the payment attempt can time out. Omitting sandbox altogether is also fine — the requirement only applies once you opt in to sandboxing.

Supported event types:

  • checkout.success — payment completed
  • checkout.failed — payment was attempted and failed
  • checkout.closed — customer dismissed checkout, e.g. no payment rail had liquidity for the amount. Close the iframe and do not run failure handling. The order can be reopened with the same checkout URL.

checkout.closed is not a statement that no funds were received. A partially paid order returns to method selection to pay its remaining balance, and can emit checkout.closed from there. Treat your own order state — fetched by order_id, or from webhooks — as authoritative before telling a customer nothing was charged.

Error handling

SDK helpers throw PayApiError (a subclass of Error) when:

  • the HTTP response is not OK
  • the API returns { success: false }

PayApiError carries statusCode, errorCode, responseObject, and — for validation failures — fieldErrors / formErrors. Its message includes the field-level detail, e.g. Invalid request: amount: Required.

A plain Error is thrown when required auth options are missing or the response envelope is malformed. An invalid or missing payout idempotencyKey, or an empty payoutId, throws a TypeError before any request is sent. A missing payout apiKey throws an Error before sending. These local errors are not PayApiError. Wrap SDK calls in try/catch.