Tapaya
Online PaymentsIntegration GuideNode.js SDK

Node.js SDK

Configuration, session methods, return types, retries, and errors for @tapayadot/checkout.

@tapayadot/checkout is the server-side TypeScript SDK for Tapaya Checkout. This reference describes version 0.3.0.

DetailValue
Package@tapayadot/checkout
Version0.3.0
RuntimeNode.js 22.13.0 or newer, ES modules, TypeScript declarations included
Browser scriptTapaya.js 0.2.0, loaded for Embedded Checkout
Sourcetapayadot/checkout-node
npm install @tapayadot/checkout
import { Tapaya } from '@tapayadot/checkout';

const tapaya = new Tapaya();

The client reads TAPAYA_SECRET_KEY from the server environment. The package also contains the browser loader and React hook for Embedded Checkout. The loader fetches Tapaya.js 0.2.0 from https://js.tapaya.com/checkout/0.2.0/checkout.js; the browser script version is independent of this package version. It does not load .env files. Keep the key and client in server-only code. The Hosted Checkout guide covers creating an order, redirecting the customer, and verifying payment.

Configuration

const tapaya = new Tapaya(apiKey, {
	environment: 'sandbox',
	timeoutMs: 30_000,
	maxRetries: 2,
})
OptionDefaultDescription
apiKey (first argument)TAPAYA_SECRET_KEYA merchant checkout key, or the organization Secret key in platform mode.
environmentTAPAYA_ENVIRONMENT, then production for a tapaya_live_ key and sandbox otherwisesandbox (https://api.sandbox.tapaya.com) or production (https://api.tapaya.com). A live key outside production, or a test key in production, throws when the client is created.
baseUrlTAPAYA_BASE_URL, then the URL selected by environmentOverrides the API URL for hosted and embedded calls.
timeoutMs30000Timeout for each attempt, in milliseconds.
merchantTokenNoneMerchant token, sent as X-Tapaya-Merchant-Token. Required in platform mode.
maxRetries2Retries after a network error, a timeout, HTTP 429, 502, 503, or 504, or a create still in progress.
fetchGlobal fetchCustom fetch implementation, for example to add a proxy or instrumentation.

To use a custom API endpoint, set TAPAYA_BASE_URL=https://api.example.com on your server. An explicit baseUrl takes precedence over TAPAYA_BASE_URL; both override environment selection.

The client resolves the API key and API URL once, when it is constructed. Use a key that matches the selected environment. API, return, and hosted checkout URLs must use HTTPS, except that HTTP is allowed for localhost, 127.0.0.1, and [::1] outside NODE_ENV=production. The SDK checks the current NODE_ENV each time it validates a local HTTP URL.

timeoutMs must be an integer from 1 to 2,147,483,647. maxRetries must be a nonnegative safe integer. The default retry count allows up to three attempts per call, each with its own timeout.

Each method also accepts signal, timeoutMs, and maxRetries for a single request:

const current = await tapaya.checkout.sessions.get(sessionId, {
	signal: request.signal,
	timeoutMs: 5_000,
})

When the signal aborts, the method stops immediately, without retrying, and rejects with the signal's reason.

Checkout sessions

Select a merchant

In merchant mode, a merchant checkout key selects its merchant. Use new Tapaya() without a merchantToken.

In platform mode, one organization Secret key serves many merchants. Every request needs a merchant token; there is no default merchant, and a request without one fails with TapayaAuthenticationError. Copy tokens from the merchants table in Checkout settings and pass the order's token on both creation and retrieval:

const tapaya = new Tapaya(process.env.TAPAYA_SECRET_KEY)
const session = await tapaya.checkout.sessions.create(params, {
	merchantToken: order.merchantToken,
	idempotencyKey: order.checkoutAttemptKey,
})
const current = await tapaya.checkout.sessions.get(session.id, {
	merchantToken: order.merchantToken,
})

You can also set a default with new Tapaya(key, { merchantToken }). The token applies to hosted and embedded calls. Tapaya rejects tokens outside the key's organization. With a merchant key, a token is optional and must name the key's own merchant. See Checkout authentication.

Create a session

tapaya.checkout.sessions.create(params, options?) requires merchantOrderId, amount, and currency. merchantOrderId is your order reference, 1 to 200 characters. An order can be paid only once; a new session for an unpaid order replaces the previous one. See One payment per order. amount is the final total, including tax and shipping, an integer between 1 and 2,147,483,647 minor units. currency is a three-letter ISO 4217 code. Tapaya stores and returns it uppercase.

Optional fields:

FieldDescription
localeLanguage of the hosted page, such as en. Defaults to en.
successUrl, cancelUrlReturn URLs. Default to the URLs in your Checkout settings.
tax, shippingTax and shipping included in amount, in minor units.
taxRateSingle tax rate in percentage points, such as 21.
taxBreakdownTax per rate, [{ taxRate, tax }], for orders with mixed rates. Use instead of taxRate: the types reject both together.
itemsProducts shown on the hosted page: reference, name, description, imageUrl, quantity, and unitAmount. Items are for display only and do not change the amount charged.
customerOptional email, billingAddress, and shippingAddress. Send only the details you collect.

Before sending, the SDK checks types, required fields, integer amounts, the currency format, and a maximum email length of 254 characters. Return URLs must be absolute HTTPS URLs, with the local HTTP exception described under Configuration. Tapaya validates business rules such as email format, address limits, and country codes, and reports problems as TapayaInvalidRequestError. See Checkout Sessions for field rules, tax totals, and customer address limits.

Get a session

tapaya.checkout.sessions.get(id, options?) returns the current state of a session. The ID must be a nonblank string of at most 200 characters; . and .. are invalid. The SDK URL-encodes the ID.

Hosted creation and retrieval return a HostedCheckoutSession. For the embedded methods prepare(), verify(), and configuration(), see Embedded Checkout.

Hosted session fields:

FieldDescription
idSession ID, such as cs_Y7u2d.
urlHosted payment page. Redirect to it unchanged.
merchantOrderId, amount, currencyOrder details to compare with your stored order.
statusopen, completed, or expired. Sessions accept new payments for 30 minutes. New values may be added.
paymentStatusunpaid, successful, failed, cancelled, or action_needed. New values may be added.
paymentReferenceToken of the latest payment attempt, or null before the first attempt.
tax, shipping, taxRate, taxBreakdownTotals sent when the session was created. Default to 0, 0, null, and [].
itemsItems sent when the session was created, or an empty array.
createdAt, expiresAt, completedAtISO 8601 timestamps. completedAt is null until payment succeeds.

Handle unknown status and paymentStatus values, for example by treating them as not yet paid. Only paymentStatus: 'successful' proves payment.

A declined card is a payment outcome, not an error. The session stays open with paymentStatus: 'failed', and the customer can try again. While Tapaya confirms an uncertain outcome, the session stays open and unpaid. There are no webhooks yet; poll get() from a reconciliation job.

Idempotency and retries

Every create request sends an Idempotency-Key. An explicit key must be a nonblank string of printable ASCII characters. Tapaya accepts at most 250 characters. If you omit idempotencyKey, the SDK generates a random key for each call. Within that call, retries reuse the key, so a retry never creates a second session.

To stay safe across separate calls and process restarts, store a key with the order and pass it every time you create a session for that attempt, with the same parameters. Tapaya returns the original session instead of creating a new one. Use a new key only for a new checkout attempt, never to retry an uncertain result.

A repeated hosted create returns the same session with its current status and paymentStatus. Call tapaya.checkout.sessions.get(session.id) to check the status again before fulfilling the order.

For the same merchant, hosted retries must use the same request body and credential mode: merchant checkout key or organization Secret key. Changing either returns HTTP 409 with code API-0025. Switching credential modes conflicts even when the body is identical, because each mode uses its own redirect settings.

The SDK retries both methods after network errors, timeouts, and HTTP 429, 502, 503, and 504. It also retries a create that fails with HTTP 409 API-0024. Retries send the same key and body, so they return the original session. The SDK waits between attempts with exponential backoff and jitter, and honors Retry-After up to 10 seconds. When Tapaya asks for a longer wait, the SDK stops retrying and throws the error for that HTTP status: TapayaRateLimitError for 429, TapayaServerError for 502, 503, or 504, or TapayaConflictError for 409. Only TapayaRateLimitError exposes the requested delay as retryAfterMs; other HTTP errors retain the Retry-After header in headers. All retries share the maxRetries budget. Set maxRetries: 0 to turn retries off.

Never switch to a new key to get past an uncertain result. The original request may already have created a session; with a new key and the same unpaid order, the new session replaces it.

Errors

SDK error classes extend TapayaError. An aborted request rejects with the signal's reason.

ErrorWhen
TapayaErrorMissing API key or invalid client configuration; base class of SDK errors.
TapayaValidationErrorParameters failed validation before a request was sent.
TapayaAuthenticationErrorHTTP 401: the key is missing or invalid, the merchant token is missing in platform mode, or the token does not match an active merchant.
TapayaInvalidRequestErrorHTTP 400 or 422: Tapaya rejected the parameters.
TapayaPermissionErrorHTTP 403.
TapayaNotFoundErrorHTTP 404: the session does not exist for this merchant.
TapayaConflictErrorHTTP 409. code is API-0025 when the idempotency key was already used with different parameters. Creating a session for an order that is already paid or has a payment in progress also returns 409.
TapayaRateLimitErrorHTTP 429 after retries, or right away when Retry-After is longer than 10 seconds. retryAfterMs holds the requested delay, when Tapaya sends one.
TapayaServerErrorHTTP 5xx. Only 502, 503, and 504 are retried, unless retries are disabled or Retry-After exceeds 10 seconds. Other 5xx statuses fail immediately.
TapayaApiErrorBase class of the HTTP errors above, and any other HTTP error status.
TapayaConnectionErrorThe request failed or the response was lost after retries. The original error is in cause.
TapayaTimeoutErrorA TapayaConnectionError for an attempt that exceeded timeoutMs.
TapayaResponseErrorTapaya returned a response the SDK could not read.

HTTP errors carry status, the Tapaya error code, fieldErrors ({ field, message, code? }[]), the response headers, and requestId from the X-Request-Id header, when present. The backend does not currently set this header. Include the session ID or order reference and the request time in support requests, along with requestId if available. TapayaResponseError carries status, headers, and requestId too. TapayaValidationError carries fieldErrors too, with field set to the parameter path, such as customer.email.

import { TapayaConnectionError, TapayaError, TapayaValidationError } from '@tapayadot/checkout'

try {
	const session = await tapaya.checkout.sessions.create(params, { idempotencyKey })
	return Response.redirect(session.url, 303)
} catch (error) {
	if (error instanceof TapayaValidationError) {
		console.error(error.fieldErrors)
	} else if (error instanceof TapayaConnectionError) {
		// The outcome is unknown. Retry later with the same idempotency key.
	} else if (error instanceof TapayaError) {
		console.error(error.message)
	}
	throw error
}

Exported types

The package exports TapayaEnvironment, TapayaOptions, RequestOptions, CreateSessionOptions, CreateCheckoutSessionParams, CheckoutSessions, CheckoutSession, CheckoutSessionStatus, CheckoutPaymentStatus, CheckoutItem, TaxBreakdownEntry, CheckoutCustomer, CheckoutContactAddress, and TapayaFieldError.

VERSION contains the SDK version. Types use named imports with import type:

import type { CheckoutSession, CreateCheckoutSessionParams } from '@tapayadot/checkout';

Upgrade from 0.2.x

  • The browser loader loads Tapaya.js 0.2.0, which supports Apple Pay and Google Pay. It rejects an already loaded 0.1.x script. Update any script tag you manage to https://js.tapaya.com/checkout/0.2.0/checkout.js.
  • environment: 'production' supports both hosted and embedded payments. configuration() returns environment: 'production' with live gateway keys.
  • Without an explicit environment or TAPAYA_ENVIRONMENT, a tapaya_live_ key selects production. Credentials that do not match the selected environment fail during client construction. baseUrl still overrides the API URL.