worldpay-sdk
v1.0.0
Published
Complete, production-grade TypeScript SDK for the Worldpay payment platform — Access REST APIs, WPG (XML Gateway), cnpAPI, RAFT/Express in-store, Marketplaces, Reporting, and Webhooks.
Maintainers
Readme
worldpay-sdk
A complete, production-grade TypeScript SDK for the Worldpay payment platform — Access REST APIs, the WPG XML Gateway, cnpAPI, RAFT 610 / Element Express card-present rails, Marketplaces, Reporting, and Webhooks, all in one dependency-light package.
- Dual ESM/CJS, fully typed, zero runtime dependencies beyond
fast-xml-parser - Built-in retries with exponential backoff + jitter, a per-API circuit breaker, request timeouts, and structured telemetry hooks
- One
Worldpayclient for every API surface — no juggling separate SDKs for Access, WPG, and cnpAPI - Runtime-agnostic core (Node 18+, Bun, Deno, Cloudflare Workers, browsers) — Node-only pieces (RAFT's raw TCP/TLS transport) are dynamically imported so they never affect other runtimes
Install
npm install worldpay-sdkQuick start
import { Worldpay } from "worldpay-sdk";
const worldpay = new Worldpay({
username: process.env.WORLDPAY_USERNAME,
password: process.env.WORLDPAY_PASSWORD,
environment: "try", // or "live"
});
const payment = await worldpay.payments.authorize({
transactionReference: "order-1234",
merchant: { entity: "default" },
instruction: {
value: { amount: 1999, currency: "USD" },
paymentInstrument: {
type: "card/plain",
cardHolderName: "Ada Lovelace",
cardNumber: "4444333322221111",
cardExpiryDate: { month: 12, year: 2030 },
cvc: "123",
},
},
});
if (payment.outcome === "authorized") {
await worldpay.payments.settle(payment.paymentId!);
}Credentials can also be supplied via environment variables (WORLDPAY_USERNAME, WORLDPAY_PASSWORD, WORLDPAY_ENVIRONMENT, WORLDPAY_API_VERSION), so new Worldpay() works with no arguments in most deployments.
What's covered
| Area | Resource(s) |
|---|---|
| Orchestrated payments | worldpay.payments |
| Modular card payments (CIT/MIT) | worldpay.cardPayments, CardPaymentsFeatures |
| Alternative payment methods (28+) | worldpay.apms, Apm.* builders |
| 3-D Secure | worldpay.threeDs |
| Fraud & SCA exemptions | worldpay.fraudSight, worldpay.exemptions |
| Tokenization | worldpay.tokens, worldpay.networkPaymentTokens, worldpay.securityTokenService, worldpay.forwardApi, TokenImport, CustomerEventService |
| Payouts & money movement | worldpay.cardPayouts, worldpay.accountPayouts, worldpay.moneyTransfers, worldpay.fx, worldpay.accountTransfers, worldpay.balances, worldpay.statements |
| Queries & verification | worldpay.paymentQueries, worldpay.cardBin, worldpay.verifications, AccountUpdater |
| Hosted checkout | worldpay.hpp |
| Partner / marketplace | worldpay.boarding, worldpay.leads, worldpay.parties, worldpay.splitPayments, PartnerNotifications, TerminalLeaseNotifications |
| Reporting | worldpay.batchTransactions, Emaf, CnpBatch |
| Webhooks | WorldpayWebhooks |
| WPG (XML Direct integration) | worldpay.wpg, WpgBuilder, WpgParser, WpgFeatures |
| cnpAPI (Vantiv) | worldpay.cnp, CnpBuilder, CnpParser |
| RAFT 610 (card-present, TCP/TLS) | RaftClient, RaftMessages |
| Element Express (semi-integrated) | ExpressClient |
Error handling
Every failure surfaces as a WorldpayError subclass:
import { WorldpayError, WorldpayApiError } from "worldpay-sdk";
try {
await worldpay.payments.authorize(request);
} catch (err) {
if (WorldpayError.isWorldpayError(err)) {
console.error(err.type, err.status, err.message, err.validationErrors);
if (err.retryable) {
// network / timeout / 429 / 5xx — safe to retry after backoff
}
}
throw err;
}| Class | When |
|---|---|
| WorldpayApiError | Non-2xx response from Worldpay with a parseable body |
| WorldpayValidationErrorException | Local request validation failed before sending |
| WorldpayConfigurationError | Missing/invalid credentials or config |
| WorldpayCircuitOpenError | The circuit breaker for that API is currently open |
| WorldpayWebhookError | Webhook body failed to parse or a handler threw |
Resilience: retries & circuit breaker
Every request automatically retries on network errors, timeouts, HTTP 429, and HTTP 5xx, using full-jitter exponential backoff. A per-API circuit breaker trips after repeated failures and short-circuits further calls until a cool-down window elapses:
const worldpay = new Worldpay({
retryCount: 3, // default
retryBaseDelayMs: 250, // default
circuitBreaker: true, // default
circuitBreakerThreshold: 5, // default
circuitBreakerResetMs: 30_000,
timeoutMs: 30_000,
onTelemetry: (event) => metrics.record(event),
});
// Inspect breaker state, e.g. for a /healthz endpoint:
worldpay.circuitStatus(); // { payments: "closed", wpg: "open", ... }Disable retries for a single call with { noRetry: true }, or override the idempotency key with { idempotencyKey }.
Webhooks
import { WorldpayWebhooks } from "worldpay-sdk";
import express from "express";
const app = express();
app.post("/worldpay/webhook", express.text({ type: "*/*" }), (req, res) => {
const event = WorldpayWebhooks.parse(req.body);
switch (event.type) {
case "settled":
fulfillOrder(event.paymentId!);
break;
case "chargedBack":
flagForReview(event.paymentId!);
break;
}
res.sendStatus(200);
});WPG (XML Direct integration)
const result = await worldpay.wpg.authorise({
orderCode: crypto.randomUUID(),
description: "Order #1234",
amount: { value: 1999, currencyCode: "GBP" },
card: { cardNumber: "4444333322221111", expiryMonth: 12, expiryYear: 2030, cvc: "123" },
});
if (result.ok) {
await worldpay.wpg.capture({ orderCode: result.orderCode!, amount: { value: 1999, currencyCode: "GBP" } });
}cnpAPI (Vantiv)
const result = await worldpay.cnp.sale({
orderId: "order-1234",
amountCents: 1999,
card: { number: "4444333322221111", expDate: "1230", cardValidationNum: "123" },
});
console.log(result.approved); // true if response === "000"RAFT 610 (card-present)
The ISO 8583 bitmap wire format used in production is proprietary and supplied by your Worldpay Implementation Manager. RaftMessages builds strongly-typed messages for every transaction type; RaftClient handles TCP/TLS framing with a swappable codec:
import { RaftClient, RaftMessages, type RaftCodec } from "worldpay-sdk";
const myIso8583Codec: RaftCodec = { serialize, deserialize }; // supplied by your IM
const client = new RaftClient({ host: "raft.example.com", port: 9001, codec: myIso8583Codec });
const response = await client.submit(
RaftMessages.auth({ pan, expiry, amountCents: 1999, merchantId, terminalId, stan: "000123" }),
);Configuration reference
| Option | Env var | Default |
|---|---|---|
| username / password | WORLDPAY_USERNAME / WORLDPAY_PASSWORD | — |
| environment | WORLDPAY_ENVIRONMENT | "try" |
| apiVersion | WORLDPAY_API_VERSION | "2025-01-01" |
| wpgMerchantCode/Username/Password | WORLDPAY_WPG_* | — |
| cnpMerchantId/Username/Password | WORLDPAY_CNP_* | — |
| timeoutMs | — | 30000 |
| retryCount | — | 3 |
| fetch | — | global fetch |
Development
npm install
npm run typecheck
npm run lint
npm test
npm run buildLicense
MIT
