Production-grade TypeScript/Node.js client for the Adyen Payments Platform.
Full coverage of all 200+ Adyen API endpoints — Checkout, Management, Balance Platform, Transfers, Capital, Legal Entity, Classic APIs — with webhooks, retry, circuit breaker, rate limiting, and telemetry.
npm install adyen-sdkNode.js ≥ 18 required (uses native fetch and crypto).
import { Adyen } from "adyen-sdk";
const client = new Adyen({
apiKey: process.env.ADYEN_API_KEY!,
environment: "test", // "test" | "live"
merchantAccount: "YourMerchantECOM",
});
// Create a payment session
const result = await client.checkout.sessions.create({
amount: { currency: "EUR", value: 1000 },
merchantAccount: "YourMerchantECOM",
reference: "order-1234",
returnUrl: "https://yourapp.com/result",
});
if (result.ok) {
// Pass result.data.id and result.data.sessionData to your frontend
console.log(result.data.id);
} else {
console.error(result.error.message);
}Every API call returns Promise<Result<T>> — a discriminated union with no exceptions:
type Result<T> =
| { ok: true; data: T }
| { ok: false; error: AdyenError };const result = await client.checkout.modifications.capture("PSP-REF", {
merchantAccount: "YourMerchantECOM",
amount: { currency: "EUR", value: 1000 },
});
if (result.ok) {
console.log("Captured:", result.data);
} else {
const { type, status, message, retryable } = result.error;
if (type === "rate_limited" && retryable) scheduleRetry();
}type |
Status | retryable |
|---|---|---|
auth_error |
401, 403 | false |
not_found |
404 | false |
validation_error |
422 | false |
api_error |
400–499 | false |
rate_limited |
429 | true |
server_error |
500–599 | true |
network_error |
— | true |
timeout |
— | true |
config_error |
— | false |
webhook_validation_error |
— | false |
const client = new Adyen({
apiKey: "AQEyhmfxK...", // Required
environment: "test", // "test" | "live"
merchantAccount: "YourMerchant",
timeout: 30_000, // ms
connectTimeout: 10_000, // ms
maxRetries: 3, // on 429 / 5xx
retryDelay: 500, // ms, doubles each attempt
webhookHmacKey: "44782DEF...",
checkoutApiVersion: "72",
managementApiVersion: "3",
balancePlatformApiVersion: "2",
transferApiVersion: "4",
legalEntityApiVersion: "4",
capitalApiVersion: "1",
});// Sessions (Drop-in / Components)
await client.checkout.sessions.create({ amount, merchantAccount, reference, returnUrl });
await client.checkout.sessions.get(sessionId, sessionResult);
// Payments
await client.checkout.payments.listMethods({ merchantAccount, amount, countryCode });
await client.checkout.payments.create({ amount, merchantAccount, reference, returnUrl, paymentMethod });
await client.checkout.payments.submitDetails({ details, paymentData });
// Modifications
await client.checkout.modifications.capture(pspRef, { merchantAccount, amount });
await client.checkout.modifications.refund(pspRef, { merchantAccount, amount });
await client.checkout.modifications.cancel(pspRef, { merchantAccount });
await client.checkout.modifications.reverse(pspRef, { merchantAccount });
await client.checkout.modifications.cancelByReference({ merchantAccount, reference });
await client.checkout.modifications.updateAmount(pspRef, { merchantAccount, amount });
// Payment Links
await client.checkout.paymentLinks.create({ amount, merchantAccount, reference });
await client.checkout.paymentLinks.get(linkId);
await client.checkout.paymentLinks.update(linkId, { status: "expired" });
// Recurring / Tokens
await client.checkout.recurring.listTokens({ merchantAccount, shopperReference });
await client.checkout.recurring.deleteToken(storedPaymentMethodId);
// Orders, Donations, Utility
await client.checkout.orders.getBalance(params);
await client.checkout.donations.create(params);
await client.checkout.utility.getApplePaySession(params);import { createWebhookMiddleware, EventCode } from "adyen-sdk/webhooks";
// Express middleware
app.post("/webhooks/adyen",
express.raw({ type: "application/json" }),
createWebhookMiddleware({
hmacKey: process.env.ADYEN_HMAC_KEY!,
handler: async (eventCode, item) => {
if (eventCode === EventCode.AUTHORISATION && item.success === "true") {
await Orders.markPaid(item.merchantReference, item.pspReference);
}
if (eventCode === EventCode.CHARGEBACK) {
await Disputes.open(item);
}
},
})
);Manual validation:
import { validateHmac, parseWebhookBody, dispatch } from "adyen-sdk/webhooks";
const payload = parseWebhookBody(rawBody);
// validateAllHmac throws AdyenError on invalid signature
validateAllHmac(payload, hmacKey);
await dispatch(payload, myHandler);Balance Platform webhooks sign the full body:
import { validateBalancePlatformHmac } from "adyen-sdk/webhooks";
const isValid = validateBalancePlatformHmac(rawBody, receivedHmac, hmacKey);// Companies & Merchants
await client.management.companies.list({}, client.config);
await client.management.merchants.create({ legalEntityId }, client.config);
await client.management.merchants.activate(merchantId, client.config);
// Webhooks
await client.management.webhooks.createMerchant(merchantId, webhookParams, client.config);
await client.management.webhooks.generateMerchantHmac(merchantId, webhookId, client.config);
await client.management.webhooks.testMerchant(merchantId, webhookId, params, client.config);
// Payout Settings
await client.management.payoutSettings.add(merchantId, params, client.config);
await client.management.payoutSettings.list(merchantId, client.config);
// Terminal Settings (20 variants: company/merchant/store/terminal × settings/logo)
await client.management.terminalSettings.getMerchantSettings(merchantId, client.config);
await client.management.terminalSettings.updateTerminalLogo(terminalId, params, client.config);
await client.management.terminalSettings.getStoreLogoById(storeId, client.config);
// Terminal Orders
const orders = client.management.terminalOrdersCompany(companyId);
await orders.list({}, );// Onboarding flow
await client.balancePlatform.createAccountHolder({ legalEntityId }, client.config);
await client.balancePlatform.createBalanceAccount({ accountHolderId }, client.config);
await client.balancePlatform.createPaymentInstrument({ balanceAccountId, type: "card" }, client.config);
// Sweeps
await client.balancePlatform.createSweep(accountId, { schedule, counterparty }, client.config);
// Card PIN
await client.balancePlatform.getPublicKey(client.config);
await client.balancePlatform.changePin({ encryptedPin, token }, client.config);
// SCA Devices
await client.balancePlatform.beginScaDeviceRegistration(params, client.config);
await client.balancePlatform.finishScaDeviceRegistration(deviceId, params, client.config);
// Transaction Rules
await client.balancePlatform.createTransactionRule({ entityKey, type: "velocity" }, client.config);
// Balance Webhook Settings
await client.balancePlatform.createBalanceWebhookSetting(accountId, params, client.config);
// Transfer Limits
await client.balancePlatform.createPlatformLimit(platformId, params, client.config);
await client.balancePlatform.approveBalanceAccountLimits(accountId, params, client.config);// Transfers
await client.transfers.create({ amount, category: "internal", balanceAccountId, counterparty }, client.config);
await client.transfers.list({ balanceAccountId }, client.config);
await client.transfers.listTransactions({ balanceAccountId, createdSince }, client.config);
// Capital
await client.capital.listDynamicOffers(client.config);
await client.capital.requestGrant({ grantOfferId }, client.config);
// Raise Disputes (cardholders)
await client.raiseDisputes.raise({ transactionId, reason }, client.config);
await client.raiseDisputes.addAttachment(disputeId, { content, contentType }, client.config);await client.legalEntity.create({ type: "individual", individual: { name, email } }, client.config);
await client.legalEntity.uploadDocument({ type: "PASSPORT", content }, client.config);
await client.legalEntity.acceptToS(id, tosDocId, { acceptedBy, ip }, client.config);
await client.legalEntity.getOnboardingLink(id, { returnUrl }, client.config);await client.classicPayments.authorise({ amount, merchantAccount, paymentMethod }, client.config);
await client.classicPayments.capture({ merchantAccount, originalReference, modificationAmount }, client.config);
await client.classicAccount.createAccountHolder(params, client.config);
await client.classicFund.payoutAccountHolder(params, client.config);import { sessions, modifications } from "adyen-sdk";
import { buildConfig } from "adyen-sdk";
const config = buildConfig({ apiKey: "...", environment: "test" });
const result = await sessions.create({ ... }, config);
await modifications.refund(pspRef, { merchantAccount, amount }, config);const unsub = client.onTelemetry((event) => {
if (event.type === "request.stop") {
metrics.histogram("adyen.request.duration_ms", event.durationMs ?? 0, {
method: event.method,
status: String(event.httpStatus ?? 0),
});
}
});
// Later: unsub() to detach| Event | Fields |
|---|---|
request.start |
method, url, body (PCI-field redacted) |
request.stop |
method, url, durationMs, httpStatus, ok |
- Retry — exponential backoff on 429 / 5xx (
maxRetries,retryDelay) - Circuit breaker — opens after 5 consecutive failures; half-opens after 30s
- Rate limiter — token bucket, 100 req/s sustained, burst 200
- Idempotency — auto-generated
Idempotency-Keyon every POST
Dual-published. Works in ESM and CommonJS:
// ESM
import { Adyen } from "adyen-sdk";
// CJS
const { Adyen } = require("adyen-sdk");MIT