Skip to content

fintech-sdk/adyen-sdk

Repository files navigation

adyen-sdk

npm License: MIT

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.


Installation

npm install adyen-sdk

Node.js ≥ 18 required (uses native fetch and crypto).


Quick Start

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);
}

Result Type

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();
}

Error types

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

Configuration

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",
});

APIs

Checkout

// 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);

Webhooks

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);

Management

// 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({}, );

Balance Platform

// 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 & Capital

// 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);

Legal Entity (KYC)

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);

Classic APIs

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);

Functional style (no class instance needed)

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);

Telemetry

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

Events

Event Fields
request.start method, url, body (PCI-field redacted)
request.stop method, url, durationMs, httpStatus, ok

Reliability

  • 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-Key on every POST

ESM + CJS

Dual-published. Works in ESM and CommonJS:

// ESM
import { Adyen } from "adyen-sdk";

// CJS
const { Adyen } = require("adyen-sdk");

License

MIT

About

Production-grade TypeScript/Node.js client for the Adyen Payments Platform — all endpoints, webhooks, and financial product APIs.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors