Utopia PaymentsDocs

Node.js

Install the official Node.js and TypeScript library for the Utopia Payments API.

  • Zero dependencies, ESM and CommonJS, full TypeScript types
  • Every create sends an Idempotency-Key, so retries never double-charge
  • Network errors, 429 and 5xx are retried with backoff
  • Lists paginate automatically with for await
  • webhooks.unwrap() verifies Standard Webhooks signatures

Requires Node.js 20.3 or later.

Install

npm install @utopia-payments/node

The package is published from the public Utopia-Payments/utopia-node repository.

Quick start

Create a secret key in Dashboard → Developers and keep it on your server, for example in UTOPIA_API_KEY.

import Utopia from '@utopia-payments/node';

const utopia = new Utopia({ apiKey: process.env.UTOPIA_API_KEY });

// One-time payment: send the customer to the hosted checkout.
const session = await utopia.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_…', quantity: 1 }],
  customer: { email: 'customer@example.com' },
  return_url: 'https://your-store.com/thank-you',
  metadata: { order_id: '1001' },
});
redirect(session.checkout_url);

Amounts are integer minor units: 34900 is AED 349.00. See Currencies and amounts, especially for KWD, BHD and OMR.

Subscriptions

const plan = await utopia.products.create({
  name: 'Pro',
  price: 9900,
  currency: 'AED',
  billing: 'recurring',
  billing_interval: 'month',
});

const session = await utopia.checkoutSessions.create({
  product_cart: [{ product_id: plan.product_id }],
  customer: { email: 'member@example.com' },
  return_url: 'https://your-app.com/billing',
});

// Later
await utopia.subscriptions.cancel('sub_…', { atPeriodEnd: true });

Webhooks

Verify every delivery against the raw request body:

Next.js route handler
export async function POST(request: Request) {
  const event = utopia.webhooks.unwrap(
    await request.text(),
    request.headers,
    process.env.UTOPIA_WEBHOOK_SECRET!,
  );
  // …
  return new Response(null, { status: 204 });
}

See Webhooks for an Express example and the events.

Webhooks can also be used without an API key when an application only needs to verify deliveries:

import { Webhooks } from '@utopia-payments/node';

const event = new Webhooks().unwrap(rawBody, headers, process.env.UTOPIA_WEBHOOK_SECRET!);

Resources

The client exposes account, products, customers, checkoutSessions, payments, subscriptions, webhookEndpoints and events. webhooks is the key-free signature verifier.

Pagination

const page = await utopia.payments.list({ limit: 50, status: 'succeeded' });

for await (const payment of utopia.payments.list({ limit: 100 })) {
  console.log(payment.payment_id, payment.total_amount);
}

Errors

import { NotFoundError, UtopiaError } from '@utopia-payments/node';

try {
  await utopia.payments.retrieve('pay_…');
} catch (error) {
  if (error instanceof NotFoundError) {
    // …
  } else if (error instanceof UtopiaError) {
    console.log(error.status, error.code, error.message);
  }
}

Error classes: InvalidRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, RateLimitError, APIError, APIConnectionError, WebhookVerificationError.

Options

new Utopia({
  apiKey: 'sk_live_…',
  timeout: 30_000, // ms per request
  maxRetries: 2,
  baseUrl: 'https://utopia-payments.com/api/v1',
});

utopia.livemode tells you whether a client uses a live or a test key.

CommonJS is supported by the prepared package as well:

const { Utopia, Webhooks } = require('@utopia-payments/node');

On this page