PaybytokenDocs
SDK · Node

Node SDK

Create Checkout Sessions, manage payment resources and verify webhooks on your server.

Use @paybytoken/node in trusted server code. It provides typed access to Checkout Sessions, Payment Intents, Payment Requests, customer deposits and withdrawals, refunds, merchant balances, payouts, events, webhook endpoints and private-beta Paybytoken Pay handoffs.

Install

pnpm add @paybytoken/node

Initialize the client

import Paybytoken from '@paybytoken/node'

const paybytoken = new Paybytoken(
  process.env.PAYBYTOKEN_SECRET_KEY!,
)

Use a test key during development and a live key only in your production secret store.

When one order can offer stablecoin, card, Apple Pay or Google Pay, configure the independent Payments Router credential as well:

const paybytoken = new Paybytoken(process.env.PAYBYTOKEN_SECRET_KEY!, {
  payments: {
    apiKey: process.env.PAYBYTOKEN_PAYMENTS_API_KEY!,
    baseUrl: 'https://payments-api.paybytoken.io',
  },
})

Core and Payments credentials are not interchangeable. The Payments URL has no version suffix; the SDK uses /v2/payments for Router resources. See Hosted Router checkout.

The default API base is https://api-prod.paybytoken.io/api/v1 and the default request timeout is 10 seconds. Override them only for an approved test deployment:

const paybytoken = new Paybytoken(process.env.PAYBYTOKEN_SECRET_KEY!, {
  baseUrl:
    process.env.PAYBYTOKEN_API_BASE_URL ?? 'https://api-prod.paybytoken.io/api/v1',
  timeout: 15_000,
})

Create a Checkout Session

const session = await paybytoken.checkoutSessions.create({
  currency: 'usd',
  line_items: [
    {
      quantity: 1,
      unit_amount: '50.00',
      product_data: {
        name: 'Account balance top-up',
      },
    },
  ],
  supported_tokens: [
    { currency: 'USDC', chain: 'base' },
    { currency: 'USDC', chain: 'ethereum' },
  ],
  success_url: 'https://shop.example.com/order/success',
  cancel_url: 'https://shop.example.com/cart',
})

Hosted checkout is the default. Redirect the customer to session.url.

For embedded checkout, set ui_mode: 'embedded' and provide the exact allowed_origin. For a merchant-owned interface, set ui_mode: 'custom' and confirm the selected token from your server.

Confirm custom checkout

const instructions = await paybytoken.checkoutSessions.confirm(
  session.id,
  { selected_token_id: selectedTokenId },
  session.csrf_token!,
)

Keep the CSRF token on your server. Do not accept a price, destination address, contract or atomic amount from browser input.

Create a multi-method Payment

const created = await paybytoken.payments.create(
  {
    amount: { value: '50.00', currency: 'USD' },
    options: ['stablecoin', 'card', 'apple_pay', 'google_pay'],
    line_items: [{ name: 'Starter plan', quantity: 1, unit_amount: '50.00' }],
    metadata: { order_id: 'order_123' },
  },
  'create-order_123',
)

Redirect to created.checkout_url for hosted checkout. Router selects a merchant- and mode-scoped provider connection; your server and browser choose only an option_id.

After payment, keep using the Router Payment resource:

const operations = await paybytoken.payments.getOperations(created.payment.id)

if (operations.payment.status === 'succeeded') {
  await paybytoken.payments.createRefund(
    operations.payment.id,
    { amount: '10.00' },
    `refund:${operations.payment.id}:support-case-42`,
  )
}

const reconciliation = await paybytoken.payments.listReconciliation({ limit: 100 })

Use payments.sync(paymentId) only to reconcile uncertain provider state. It is not a replacement for webhook-driven fulfillment.

Configure stablecoin checkout

const current = await paybytoken.paymentMethodConfigurations.getDefault()

await paybytoken.paymentMethodConfigurations.updateDefault({
  if_version: current.version,
  stablecoin: {
    ...current.stablecoin,
    wallets: { browser_wallet: true, manual_transfer: true },
    tokens: [{ currency: 'USDC', chain: 'base' }],
  },
})

Every new Checkout Session snapshots the resolved version. Its payment_method_options field is the authoritative contract for hosted, embedded and custom presentation.

Verify a webhook

const event = paybytoken.webhookEvents.constructEvent(
  rawBody,
  signature,
  process.env.PAYBYTOKEN_WEBHOOK_SECRET!,
)

Verify the exact raw body before parsing or modifying it. Fulfill only after a verified terminal event and make event processing idempotent.

Create a Payment Request

const request = await paybytoken.paymentRequests.create(
  {
    title: 'August services',
    customer_email: 'alex@example.com',
    currency: 'usd',
    line_items: [{ name: 'Consulting', quantity: 1, unit_amount: '50.00' }],
    supported_tokens: [{ currency: 'USDC', chain: 'base' }],
  },
  { idempotencyKey: 'payment-request:PO-1042' },
)

const finalized = await paybytoken.paymentRequests.finalize(request.id, {
  idempotencyKey: 'payment-request:PO-1042:finalize',
})

Use send, listPayments, listDeliveries, timeline, listAllPayments, and reconciliation for the complete receivables workflow. See Request a payment.

Customer balances and refunds

const customer = await paybytoken.customers.create(
  { reference: 'merchant_customer_8' },
  { idempotencyKey: 'customer:merchant_customer_8' },
)

const account = await paybytoken.customerDepositAccounts.create(
  customer.id,
  {
    address_family: 'evm',
    initial_address: { chains: ['base'] },
  },
  { idempotencyKey: `deposit-account:${customer.id}` },
)

const balances = await paybytoken.customerBalances.list(customer.id)

Use depositAssets.list() and withdrawalAssets.list() instead of hard-coding asset policies. The SDK also exposes customerDeposits, customerWithdrawals, refunds, and consumerPaymentSessions. See Build customer balances and Paybytoken Pay.

Handle API errors

import Paybytoken, { PaybytokenError } from '@paybytoken/node'

try {
  await paybytoken.checkoutSessions.get('chk_missing')
} catch (error) {
  if (error instanceof PaybytokenError) {
    console.error(error.code, error.type, error.message)
  }
  throw error
}

code is the API status when available and type is the machine-readable error category. Do not match business logic against message. Network failures and timeouts also surface as PaybytokenError; reconcile a mutation before deciding whether to retry it.

Continue with Get started, Custom checkout, or Fulfill orders with webhooks.

On this page

API Workbench

Full Explorer

Open in new tab