Testland
Browse all skills & agents

adyen-test-mode

Wraps Adyen test-mode patterns: test-API-key initialization, the canonical Adyen test cards (Visa 4111 1111 1111 1111; 5454 5454 5454 5454 3DS frictionless; 4917 6100 0000 0000 3DS 2 challenge), the per-flow result codes (Authorised / Refused / Pending / RedirectShopper / Error), the HMAC-SHA256 webhook validation, and notifications-vs-API duality (Adyen separates synchronous API calls from asynchronous notifications). Use when testing Adyen-integrated code.

Install with skills.sh (any agent)

npx skills add testland/qa --skill adyen-test-mode
View source

adyen-test-mode

Overview

Adyen's test environment is fully API-compatible with prod. Per docs.adyen.com/development-resources/testing (opens in new window), test API keys + test merchant accounts produce deterministic results based on input.

The notable difference from Stripe: Adyen separates the synchronous payment API from the asynchronous notification webhook more explicitly. Both surfaces need tests.

When to use

  • Tests for code using Adyen's Payments / Checkout / Recurring API.
  • Webhook handling tests.
  • 3DS flow tests per 3ds-test-flow-reference.

Authoring

Install

npm install @adyen/api-library
pip install Adyen

Initialize

import { Client, CheckoutAPI } from '@adyen/api-library';

const client = new Client({
  apiKey: process.env.ADYEN_TEST_API_KEY!,
  environment: 'TEST',                  // vs 'LIVE'
});
const checkout = new CheckoutAPI(client);

Test cards

Per docs.adyen.com/development-resources/test-cards-and-credentials/test-card-numbers (opens in new window):

CardBehaviour
4111 1111 1111 1111Authorised (Visa)
5555 4444 3333 1111Authorised (Mastercard)
4000 0000 0000 0119Refused (general)
5444 5555 5555 5557Refused (insufficient funds)
5454 5454 5454 54543DS 2 frictionless
4917 6100 0000 00003DS 2 challenge
4012 8888 8888 18813DS 1 (deprecated)

Test expiry: any future date. Test CVC: 737 (special "3DS") or any 3-digit.

Payment

const paymentResponse = await checkout.payments({
  amount: { currency: 'EUR', value: 1000 },
  paymentMethod: {
    type: 'scheme',
    encryptedCardNumber: 'test_4111111111111111',
    encryptedExpiryMonth: 'test_03',
    encryptedExpiryYear: 'test_2030',
    encryptedSecurityCode: 'test_737',
  },
  reference: 'order-' + uuidv4(),
  merchantAccount: process.env.ADYEN_MERCHANT_ACCOUNT!,
});

expect(paymentResponse.resultCode).toBe('Authorised');

Result codes per docs.adyen.com/online-payments/build-your-integration/payment-result-codes (opens in new window):

resultCodeMeaning
AuthorisedApproved
RefusedDeclined
CancelledCancelled
PendingAsync; final result via notification
RedirectShopper3DS / redirect required
IdentifyShopper3DS device-fingerprint step
ChallengeShopper3DS 2 challenge
ErrorFailure

Webhook (notification) handling

Adyen sends webhooks ("notifications") for every state change. Per docs.adyen.com/development-resources/webhooks/secure-webhooks/verify-hmac-signatures (opens in new window): validate via HMAC-SHA256 over a canonical-string of the payload.

import { hmacValidator } from '@adyen/api-library';
const validator = new hmacValidator();

test('webhook signature valid', () => {
  const notification = { /* notification payload */ };
  const hmacSignature = notification.additionalData.hmacSignature;
  const isValid = validator.validateHMAC(notification, process.env.ADYEN_HMAC_KEY!);
  expect(isValid).toBe(true);
});

Notification idempotency

Adyen redelivers notifications until acknowledged with HTTP 200

  • [accepted] body. Tests should verify the handler is idempotent under redelivery:
test('redelivered notification handled idempotently', async () => {
  const notif = makeTestNotification();
  await handler(notif);
  const before = await db.payments.count();
  await handler(notif);  // re-delivered
  const after = await db.payments.count();
  expect(after).toBe(before);
});

Notifications test mode

Per Adyen docs: in Customer Area, you can re-send notifications on demand for testing. Also exposes a webhook-events endpoint for replay.

Running

npm test

CI integration

jobs:
  adyen-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
      - run: npm ci && npm test
        env:
          ADYEN_TEST_API_KEY: ${{ secrets.ADYEN_TEST_API_KEY }}
          ADYEN_MERCHANT_ACCOUNT: ${{ secrets.ADYEN_TEST_MERCHANT_ACCOUNT }}
          ADYEN_HMAC_KEY: ${{ secrets.ADYEN_TEST_HMAC_KEY }}

Anti-patterns

Anti-patternWhy it failsFix
Use prod API key in testsReal settlement riskStrict TEST environment
Skip HMAC signature validationWebhook spoofingAlways validate
Treat resultCode=Pending as failureAsync; final via notificationWait for webhook
One unit test for "happy path" onlyRefused / RedirectShopper paths untestedPer-resultCode test
Hardcoded merchant account in codePer-env account; tests pass against wrong accountEnv var
Reply [accepted] even on processing-errorAdyen stops retryingReply only on successful processing
Skip 3DS 2 challenge testRequired by EU regulationsTest 4917 6100 0000 0000 path
Encrypted-data fields wrong formatAdyen rejects with cryptic errorUse Adyen-SDK encryption helpers

Limitations

  • Adyen test mode uses encrypted data placeholders. Real encryption uses Adyen Web SDK; tests use test_* placeholders.
  • Notification SLA varies. Real-time webhooks but retried-on-failure can be hours later.
  • Recurring API has separate test cards. Tokenisation scenarios need their own surface.
  • Region-specific payment methods. iDEAL / Sofort / etc. have separate test flows.

References

Related skills

3ds-test-flow-reference

Cross-gateway, protocol-level reference for 3-D Secure (3DS 2.x) test coverage. Covers the EMVCo frictionless / challenge / not-applicable flow paths, SCA under EU PSD2, and the per-PAN test cards for Stripe, Adyen, and Braintree. The gateway-specific wrappers (adyen-test-mode / stripe-test-cards-and-webhooks / braintree-test-cards) compose this skill for single-gateway work, so use one of those for a single-gateway query. Use this skill when designing multi-gateway 3DS test coverage, auditing a 3DS redirect round-trip, or investigating a challenge-flow regression that is not gateway-specific.

braintree-test-cards

Wraps Braintree (PayPal-owned) sandbox testing patterns: sandbox merchant credentials, Drop-in / Hosted Fields client-side patterns, the Transaction lifecycle (submitted_for_settlement → settled), Braintree's distinctive test-card behaviours (specific PANs trigger specific errors), and the webhook verification (Braintree Webhook Parser). Use when testing Braintree-integrated code.

chargeback-flow-test-author

Workflow-driven skill that builds the chargeback / dispute test suite: canonical reason codes (Visa 10.4 fraud, 13.1 services-not-provided; Mastercard MCC 4855), per-gateway dispute APIs (Stripe Disputes, Adyen Chargeback notifications, PayPal Disputes), the evidence-submission flow + window, and disposition outcomes (won / lost / accepted). Use when designing dispute coverage; for refunds use refund-test-matrix-builder, for webhook redelivery + idempotency use payment-webhook-replay, and for the lifecycle state model use payment-flow-states-reference.

payment-flow-states-reference

Pure-reference catalog of payment lifecycle state machines across Stripe, Adyen, PayPal, and Braintree: canonical states (created / requires_action / processing / succeeded / requires_capture / canceled / failed), authorisation vs capture, asynchronous webhook states, and refund / dispute / chargeback transitions. Use when designing tests for payment flows or auditing state-handling code; this is the state model, not a builder - to author suites on it use refund-test-matrix-builder (refunds), chargeback-flow-test-author (disputes), or payment-webhook-replay (webhook replay).

payment-webhook-replay

Workflow-driven skill that builds payment webhook replay + recovery tests. Covers the idempotency contract (every webhook handler must handle redelivery without side effects), the replay simulators (Stripe CLI `stripe trigger`, Adyen Customer Area resend, PayPal Webhook Simulator, Braintree webhook test), the signature-verification gauntlet (HMAC-SHA256 per gateway, expired-timestamps rejection), and the partial-failure recovery scenarios. Use when designing webhook robustness tests.

paypal-sandbox

Wraps PayPal Sandbox testing patterns: sandbox account creation (Business + Personal accounts in developer.paypal.com), the Orders v2 API (create / capture / refund), webhook event simulator (developer.paypal.com webhook simulator), sandbox-account-specific test cards, and the OAuth2 client-credentials flow for sandbox. Use when testing PayPal-integrated code.

pci-dss-scope-reference

Pure-reference catalog of PCI DSS v4.0 scope reduction techniques + the testable scope boundaries. Covers the SAQ levels (A through D, picked by how cardholder data flows), the PAN-storage prohibitions (only first-6 + last-4 retained; nothing else cleartext), the tokenization + hosted-fields scope-reduction patterns (Stripe Elements / Adyen Drop-in / Braintree Hosted Fields keep PAN off your servers), Network-Segmentation as PCI scope-reduction, and the testable behaviours the scope boundary creates. This is the catalog of WHY the boundary matters and what it makes testable - not a checker that verifies a given integration against the standard. Use when designing or auditing the PCI scope of a payment integration.

refund-test-matrix-builder

Workflow-driven skill that builds a refund test matrix from a payment-flow inventory: refund variants (full / partial / multiple-partials / over-refund / refund-on-disputed / refund-on-already-refunded), per-gateway nuances (Stripe, Adyen, PayPal, Braintree refund APIs), and timing variants (immediate / next-day / declined-by-bank), one test case per cell. Use for refund coverage on a new integration; for chargeback / dispute coverage use chargeback-flow-test-author, for webhook redelivery + idempotency use payment-webhook-replay, and for the state model use payment-flow-states-reference.

stripe-subscription-billing-test-author

Builds test suites for Stripe recurring-billing flows: trial-to-paid conversion, proration on plan upgrade and downgrade, dunning on failed renewal, cancel and reactivation, and the full subscription webhook event matrix (invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted, invoice.paid). Uses Stripe Billing test clocks (POST /v1/test_helpers/test_clocks) to time-travel through billing cycles without calendar delay. Distinct from stripe-test-cards-and-webhooks (one-time PaymentIntents) and payment-webhook-replay (idempotency + replay robustness). Does not cover single-event CLI replay or handler idempotency testing (see payment-webhook-replay for those). Use when authoring tests for subscription or recurring-billing integrations.

stripe-test-cards-and-webhooks

Wraps Stripe API testing patterns: test-mode initialization, the canonical test cards (4242 success; 4000 0000 0000 0002 declined; 4000 0027 6000 3184 3DS challenge per 3ds-test-flow-reference), the Stripe CLI webhook flow (`stripe listen --forward-to`), the Stripe CLI fixture commands (`stripe trigger payment_intent.succeeded`), and the webhook signature verification (Stripe-Signature header + HMAC-SHA256). Use when testing Stripe-integrated code.