SDK Reference
@zkp2p/pay-sdk creates orders and checkout URLs, and creates and manages payouts, from your backend. For checkout orders, you pass an amount and a payout destination; you get back the order and a hosted checkout URL that already carries the order token.
This reference covers @zkp2p/pay-sdk 7.x, versioned in lockstep with
@zkp2p/pay-shared.
checkQuoteAvailability forwards enabledRails. See quote availability.
If you are upgrading from 6.x, follow the v6 to v7 migration guide: merchant cashout APIs and types are now payouts, and payout webhook payloads use version 2.
Install
npm install @zkp2p/pay-sdk@7
# optional: shared types only (the SDK already depends on it)
npm install @zkp2p/pay-shared@7
@7 installs the latest published 7.x. Both packages are versioned in lockstep, and
@zkp2p/pay-sdk pulls in the matching @zkp2p/pay-shared automatically. If you are on an
earlier major version, work through the migration guides first, oldest
section first.
import {
createCheckout,
getCheckoutUrl,
redirectToCheckout,
} from '@zkp2p/pay-sdk';
CommonJS users can dynamic import:
const { createCheckout } = await import('@zkp2p/pay-sdk');
Runtime requirements
- Node.js 18+
- Browser/runtime with
fetch
The embedded-checkout helpers live on the @zkp2p/pay-sdk/embedded subpath. Resolving it
needs moduleResolution set to node16, nodenext, or bundler in your tsconfig. See
Integration options.
Security
Create orders from your backend and keep API keys server-side.
Quick example
import { createCheckout } from '@zkp2p/pay-sdk';
const checkout = await createCheckout(
{
requestedFiatAmount: '100.00',
requestedFiatCurrency: 'EUR',
destinationChainId: 8453,
destinationToken: 'USDC',
destinationAddress: '0xYourWallet',
successUrl: 'https://example.com/success',
cancelUrl: 'https://example.com/cancel',
},
{
apiBaseUrl: 'https://api.pay.peer.xyz',
checkoutBaseUrl: 'https://pay.peer.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
}
);
console.log(checkout.checkoutUrl);
// https://pay.peer.xyz/?order=...&token=...
createCheckout supports either:
requestedUsdcAmount, orrequestedFiatAmount+requestedFiatCurrency
Always set checkoutBaseUrl. Without it the SDK builds checkoutUrl on apiBaseUrl, so
the customer lands on the API host instead of the checkout host.
Hand the URL to the customer from your backend. Integration options covers the redirect, a new tab, and the embedded iframe.
TypeScript
import {
isPayoutWebhook,
type CheckoutClientOptions,
type CreateOrderRequest,
type CheckoutOrder,
type WebhookPayload,
} from '@zkp2p/pay-sdk';
const options: CheckoutClientOptions = {
apiBaseUrl: 'https://api.pay.peer.xyz',
checkoutBaseUrl: 'https://pay.peer.xyz',
apiKey: process.env.ZKPAY_API_KEY,
};
const request: CreateOrderRequest = {
requestedUsdcAmount: '50.00',
destinationChainId: 8453,
destinationToken: 'USDC',
successUrl: null,
cancelUrl: null,
notes: null,
};
// A webhook body, after verifying its signature: narrow before reading data.
function orderFromWebhook(payload: WebhookPayload): CheckoutOrder | null {
return isPayoutWebhook(payload) ? null : payload.data.order;
}
Available Functions
| Function | Description |
|---|---|
createCheckout | Create an order + checkout URL |
getCheckoutUrl | Build checkout URL |
redirectToCheckout | Redirect browser to checkout |
createCheckoutAndRedirect | Create order + redirect in one call |
getMerchant | Fetch merchant profile |
checkQuoteAvailability | Check fill availability + nearby amounts before creating an order |
createPayout | Create a payout that pays a customer out, and get its funding address |
getPayout | Fetch one payout |
listPayouts | List payouts, newest first, with filters |
cancelPayout | Cancel a payout that is awaiting funding and has received nothing |
getMerchant
function getMerchant(opts: CheckoutClientOptions): Promise<MerchantInfo>
import { getMerchant } from '@zkp2p/pay-sdk';
const merchant = await getMerchant({
apiBaseUrl: 'https://api.pay.peer.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
});
console.log(merchant.name);
console.log(merchant.tier); // 'BASE' | 'PRO' | 'CONCIERGE' | null until a plan is selected
console.log(merchant.merchantConfig?.enabledRails);
Error handling
Every SDK call that reaches the API throws PayApiError when the API answers with a non-2xx status or a success: false envelope. It extends Error and carries the detail the API sent:
class PayApiError extends Error {
statusCode: number;
errorCode?: string;
responseObject?: unknown;
fieldErrors?: Readonly<Record<string, readonly string[]>>;
formErrors?: readonly string[];
}
message is the API's message; for a 400 validation failure it is extended with a bounded per-field summary, such as Invalid request: notes: Expected object, received string, and the complete detail is on fieldErrors and formErrors.
import { createCheckout, PayApiError } from '@zkp2p/pay-sdk';
try {
await createCheckout(params, opts);
} catch (error) {
if (error instanceof PayApiError) {
console.error(error.statusCode, error.errorCode, error.message);
}
throw error;
}
Codes you can branch on when creating an order, including the plan and monthly cap codes, are listed under createCheckout errors. Transport failures and a malformed response envelope throw a plain Error.
Payout input checks fail before any request is sent:
| Input | Error | Message |
|---|---|---|
Invalid or missing idempotencyKey | TypeError | idempotencyKey must be 8-128 characters of letters, digits, "_" or "-" |
Empty payoutId | TypeError | payoutId must be a non-empty string |
Missing apiKey | Error | API key is required. Pass apiKey in options. |
Configuration
Checkout and merchant functions take CheckoutClientOptions; see Configuration.
Payout functions take PayoutClientOptions: apiBaseUrl,
a required apiKey, and optional fetcher and signal.