PayNow

TypeScript

The official PayNow TypeScript SDK wraps the Management API and Storefront API with fully typed clients, so you get autocomplete for every endpoint, request body and response. It works from plain JavaScript as well. The types are there when you want them.

The source is on GitHub and the package is published to npm as @paynow-gg/typescript-sdk. Every endpoint page in these docs also has a TypeScript tab showing the SDK call for that endpoint.


Installation

NPM

Bash
npm install @paynow-gg/typescript-sdk

PNPM

Bash
pnpm add @paynow-gg/typescript-sdk

Yarn

Bash
yarn add @paynow-gg/typescript-sdk

The SDK requires Node.js 20.3 or newer, or any runtime with a global fetch. You can also pass your own fetch implementation through the client options.

Management API

The Management client authenticates with an API key and is scoped to a single store. Keep it on your server - never ship an API key to a browser.

TypeScript
import { createManagementClient, type Management } from "@paynow-gg/typescript-sdk";

const management = createManagementClient({
  apiKey: process.env.PAYNOW_API_KEY!,
  storeId: "411486491630370816",
});

const bans: Management.BanDto[] = await management.bans.getBans({ limit: 50, ban_type: "steam" });
const ban = await management.bans.getBan("411486491630370816");

await management.bans.updateBan(ban.id, { reason: "chargeback" });
await management.bans.deleteBan(ban.id);

Endpoints are grouped by tag, so the Bans endpoints live under management.bans, Products under management.products, and so on. Arguments follow the endpoint: path parameters first, then the request body, then query parameters.

Storefront API

The Storefront client only needs a store ID. Pass a customer token to act on behalf of a signed-in customer, for example to read or modify their cart.

TypeScript
import { createStorefrontClient } from "@paynow-gg/typescript-sdk";

const storefront = createStorefrontClient({
  storeId: "411486491630370816",
  customerToken: process.env.PAYNOW_CUSTOMER_TOKEN,
});

const store = await storefront.store.getStorefrontStore();
const cart = await storefront.cart.getCart();

await storefront.cart.addLine(
  { product_id: "411486491630370816", quantity: 1 },
  { headers: { "x-paynow-customer-ip": "127.0.0.1" } },
);

Every method accepts an optional final options argument with per-request headers, an AbortSignal and a timeoutMs. That is how you forward the customer's IP address on storefront calls.

Error handling

Failed requests throw a PayNowApiError carrying the HTTP status, the error code, the message, the trace ID and any field-level validation failures.

TypeScript
import { isPayNowApiError } from "@paynow-gg/typescript-sdk";

try {
  await management.bans.getBan("nope");
} catch (error) {
  if (isPayNowApiError(error)) {
    console.error(error.status, error.code, error.message, error.traceId);
    console.error(error.errors);
    console.error(error.response.headers.get("retry-after"));
  }
}

Webhook types

The SDK ships the payload type for every webhook event under the Webhooks namespace, so a handler can be fully typed without any runtime dependency. Every payload has the same envelope: event_type, event_id and a body that differs per event.

Verify the signature first, as described in Validating Incoming Webhooks, then narrow on event_type and cast to the matching payload type.

TypeScript
import type { Webhooks } from "@paynow-gg/typescript-sdk";

const payload = JSON.parse(rawBody) as { event_type: Webhooks.WebhookEventType };

switch (payload.event_type) {
  case "ON_ORDER_COMPLETED": {
    const { body } = payload as Webhooks.OnOrderCompletedPayload;
    console.log(`Order ${body.id} completed`);
    break;
  }
  case "ON_SUBSCRIPTION_CANCELED": {
    const { body } = payload as Webhooks.OnSubscriptionCanceledPayload;
    console.log(`Subscription ${body.id} canceled`);
    break;
  }
}

Payload types are named after the event, so ON_PAYMENT_FAILED is Webhooks.OnPaymentFailedPayload. Webhooks.WebhookEventType is the union of every event name PayNow can send. The models shared between events, such as OrderDTO and CustomerDTO, are exported from the same namespace.

Other languages

TypeScript is the only SDK we publish today. Every other language can call the REST API directly - each endpoint page includes a curl example you can translate into your HTTP client of choice.