Skip to main content

createCheckoutSession

Creates a new checkout session for a payment.

Signature

function createCheckoutSession(
params: CreateSessionRequest,
opts: CheckoutClientOptions
): Promise<CreateSessionResponse>

Parameters

params: CreateSessionRequest

The SDK supports two checkout modes: exact-token (default) and exact-fiat.

Exact-Token Mode (Default)

Specify the exact USDC amount the merchant should receive. The customer pays whatever fiat amount is needed to cover this.

PropertyTypeRequiredDescription
merchantIdstringYesYour merchant ID
amountUsdcstringYesAmount in USDC (e.g., "50.00")
destinationChainIdnumberYesTarget chain ID (see Supported Chains)
destinationTokenstringYesToken address (USDC on target chain)
recipientAddressstringYesWallet to receive funds
successUrlstringNoRedirect URL after successful payment
cancelUrlstringNoRedirect URL if user cancels
metadataRecord<string, string>NoCustom key-value pairs (passed to webhooks)
enabledPaymentPlatformsPaymentPlatformType[]NoRestrict available payment platforms
checkoutMode'exact-token'NoDefaults to 'exact-token'

Exact-Fiat Mode

Specify the exact fiat amount the customer should pay. The merchant receives whatever USDC amount results after fees.

PropertyTypeRequiredDescription
merchantIdstringYesYour merchant ID
checkoutMode'exact-fiat'YesMust be 'exact-fiat'
fiatAmountstringYesFiat amount to charge (e.g., "100.00")
fiatCurrencystringYesCurrency code (e.g., "USD")
maxFeePercentagenumberNoMaximum acceptable fee percentage
destinationChainIdnumberYesTarget chain ID
destinationTokenstringYesToken address (USDC on target chain)
recipientAddressstringYesWallet to receive funds
successUrlstringNoRedirect URL after successful payment
cancelUrlstringNoRedirect URL if user cancels
metadataRecord<string, string>NoCustom key-value pairs
enabledPaymentPlatformsPaymentPlatformType[]NoRestrict available payment platforms

opts: CheckoutClientOptions

PropertyTypeRequiredDescription
apiBaseUrlstringYesAPI server URL
apiKeystringYesYour merchant API key
checkoutBaseUrlstringNoCheckout UI URL (defaults to apiBaseUrl)
fetchertypeof fetchNoCustom fetch implementation

Returns

interface CreateSessionResponse {
session: CheckoutSession;
sessionToken: string; // Required for checkout URL
checkoutUrl: string; // Pre-built checkout URL with token
bridge?: BridgeInfo; // Present for cross-chain payments
}

interface BridgeInfo {
required: boolean;
inputAmount?: string; // Amount on Base (includes fees)
outputAmount?: string; // Expected output after bridge
feeAmount?: string; // Bridge fee
minOutputAmount?: string;
estimatedTimeSeconds?: number;
}

The response includes:

  • session: Full session object with all details
  • sessionToken: One-time token required to access the checkout URL
  • checkoutUrl: Ready-to-use URL with session ID and token
  • bridge: Bridge details if payment requires cross-chain delivery
important

The sessionToken is only returned when the session is created. Store it if you need to construct checkout URLs later.

Supported Chains

Payments can be delivered to multiple chains:

Chain IDChain NameType
8453BaseEVM (Origin)
1EthereumEVM
10OptimismEVM
42161ArbitrumEVM
137PolygonEVM
324zkSync EraEVM
59144LineaEVM
534352ScrollEVM
999HyperEVMEVM
34268394551451SolanaNon-EVM
note

Payments on chains other than Base require bridging via Across Protocol. The bridge field in the response will contain details about fees and estimated time.

Recipient Address and Defaults

The recipientAddress parameter specifies where funds should be delivered. When omitted, the SDK uses your merchant's default wallet address based on the destination chain:

  • EVM chains (Base, Ethereum, Arbitrum, etc.): Uses your Privy EVM wallet address (0x...)
  • Solana: Uses your Privy Solana wallet address (base58 format)

These wallet addresses are automatically created when you first log into the merchant dashboard. You can view them in Settings → Wallets.

Address Formats

Chain TypeFormatExample
EVMHex (0x prefix)0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71
SolanaBase587K6...<base58 address>

Override Default Address

You can always specify a custom recipientAddress to override the default:

const response = await createCheckoutSession(
{
merchantId: 'merchant_abc123',
amountUsdc: '100.00',
destinationChainId: 34268394551451, // Solana
destinationToken: 'USDC',
recipientAddress: 'YourCustomSolanaAddress...', // Override default
},
opts
);
tip

If you haven't logged into the merchant dashboard, or your destination chain type doesn't have a default wallet, you must provide recipientAddress explicitly.

Examples

Basic Checkout (Exact-Token)

import { createCheckoutSession } from '@zkp2p-pay/sdk';

const response = await createCheckoutSession(
{
merchantId: 'merchant_abc123',
amountUsdc: '99.99',
destinationChainId: 8453,
destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71',
successUrl: 'https://mystore.com/order/success',
cancelUrl: 'https://mystore.com/cart',
metadata: {
orderId: 'order_12345',
customerId: 'cust_67890',
},
},
{
apiBaseUrl: 'https://api.pay.zkp2p.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
}
);

console.log('Session ID:', response.session.id);
console.log('Session Token:', response.sessionToken);
console.log('Checkout URL:', response.checkoutUrl);

Fixed Fiat Price (Exact-Fiat)

Useful when you want the customer to pay an exact fiat amount (e.g., "$100"):

const response = await createCheckoutSession(
{
merchantId: 'merchant_abc123',
checkoutMode: 'exact-fiat',
fiatAmount: '100.00',
fiatCurrency: 'USD',
maxFeePercentage: 2.0, // Accept up to 2% fee
destinationChainId: 8453,
destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71',
successUrl: 'https://mystore.com/order/success',
},
{
apiBaseUrl: 'https://api.pay.zkp2p.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
}
);

Restrict Payment Platforms

Only allow specific payment platforms:

const response = await createCheckoutSession(
{
merchantId: 'merchant_abc123',
amountUsdc: '50.00',
destinationChainId: 8453,
destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71',
enabledPaymentPlatforms: ['venmo', 'cashapp'], // Only US platforms
},
{
apiBaseUrl: 'https://api.pay.zkp2p.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
}
);

Cross-Chain Payment (Arbitrum)

const response = await createCheckoutSession(
{
merchantId: 'merchant_abc123',
amountUsdc: '100.00',
destinationChainId: 42161, // Arbitrum
destinationToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71',
},
{
apiBaseUrl: 'https://api.pay.zkp2p.xyz',
apiKey: process.env.ZKPAY_API_KEY!,
}
);

if (response.bridge?.required) {
console.log('Bridge fee:', response.bridge.feeAmount);
console.log('Estimated time:', response.bridge.estimatedTimeSeconds, 'seconds');
}

Error Handling

The function throws an error if:

  • The API key is missing or invalid
  • The request parameters are invalid
  • The API request fails
  • Fee exceeds maxFeePercentage (for exact-fiat mode)
try {
const response = await createCheckoutSession(params, opts);
} catch (error) {
console.error('Failed to create session:', error.message);
}

Notes

  • The amountUsdc should be a decimal string (e.g., "50.00", not 50)
  • The metadata object is limited to string values
  • Session IDs are unique and can be used to track the payment
  • Sessions expire after 1 hour by default
  • The sessionToken is only available at creation time