commercetools – Adyen

Integration Specification — Technical Reference
commercetools Adyen
OAuth2 (commercetools) + API Key/HMAC (Adyen) Event-Driven Webhook Orchestration
79 / 100
VIABLE
Health Score
Integration Viability Score — Proprietary Assessment
commercetools Adyen
Auth Robustness20/25
Webhook / Event Support23/25
Rate Limit Generosity16/25
Documentation Quality20/25
VERDICTA highly viable enterprise integration combining commercetools' composable commerce platform with Adyen's payment orchestration, bridged via an event-driven middleware layer that synchronises payment state across both systems in near-real-time.

Executive Summary

The commercetools ↔ Adyen integration represents one of the most common and commercially critical pairings in composable commerce architecture. commercetools acts as the system of record for orders, carts, customers, and payment objects, while Adyen handles the actual payment processing, fraud evaluation, and settlement lifecycle. The middleware layer—typically a serverless function or integration platform—is responsible for translating commercetools Cart and Order events into Adyen Checkout API calls, then feeding Adyen webhook notifications back into commercetools Payment resource state transitions. Both platforms expose mature, well-documented REST APIs, with commercetools using OAuth2 client credentials for all API access and Adyen relying on API key authentication with optional HMAC webhook signature verification. The integration supports the full payment lifecycle: authorisation, capture, partial capture, refund, cancellation, and chargeback handling—each mapped to specific commercetools Payment Transaction types and PaymentStatus states.

⚡ Accelerate your integration roadmap

Stop wrestling with API rate limits, undocumented endpoints, and unreliable webhooks. Our engineering team designs and deploys resilient, enterprise-grade integration architectures in days. Prefer to build it in-house? Leverage our recommended middleware platform.

Logical Architecture & Data Flow

Architecture Component Breakdown

commercetools Auth Server
Issues OAuth2 access tokens via the https://auth.{region}.commercetools.com/oauth/token endpoint using client_credentials flow. Tokens are scoped per API client and carry TTLs requiring proactive refresh.
commercetools Payment Resource
Central entity at /{projectKey}/payments that models payment intent, method, and all Transaction records (Authorization, Charge, Refund, CancelAuthorization). Acts as the source of truth for payment state within commercetools.
commercetools Subscriptions
The /{projectKey}/subscriptions resource enables push-based event delivery to SQS, SNS, Google Pub/Sub, or Azure Service Bus when Order and Payment resources change state—triggering downstream Adyen API calls.
Integration Middleware
Stateless orchestration layer (Lambda, Cloud Run, or iPaaS) that maps commercetools Cart/Order/Payment data to Adyen Checkout API payloads, manages idempotency keys, and routes Adyen webhook events back to commercetools Payment updates.
Adyen Checkout API
REST API at https://checkout-test.adyen.com/v71 handling POST /sessions, POST /payments, captures via POST /payments/{pspReference}/captures, refunds, cancels, and reversals. Authenticated via X-API-Key header.
Adyen Webhook Receiver
HTTPS endpoint hosted in middleware that receives Adyen Standard Notifications (AUTHORISATION, CAPTURE, REFUND, CHARGEBACK, etc.), validates HMAC signatures, and dispatches state-change updates to the commercetools Payment API.
Adyen Disputes API
Handles chargeback lifecycle via POST /defendDispute, POST /acceptDispute, and POST /supplyDefenseDocument. Feeds dispute webhook events back to commercetools Order resource for automated chargeback state tracking.
Token Vault (Stored Methods)
Adyen’s GET /storedPaymentMethods and POST /storedPaymentMethods endpoints manage tokenised card credentials, with the resulting token references stored in commercetools Customer custom fields for recurring order flows.

Authentication Architecture

commercetools uses the OAuth2 Client Credentials flow exclusively. API clients are created in the Merchant Center or via the /{projectKey}/api-clients endpoint, and each client is issued a clientId and clientSecret. The middleware exchanges these credentials at https://auth.{region}.commercetools.com/oauth/token with grant_type=client_credentials and the relevant scope (e.g. manage_payments:{projectKey}). Tokens have a configurable TTL and must be refreshed proactively. Adyen authenticates all outbound API calls via the X-API-Key HTTP header, with API keys generated per merchant account in the Adyen Customer Area. For inbound webhook security, Adyen supports HMAC signature verification: each notification payload includes an additionalData.hmacSignature field that middleware must validate using the shared HMAC key configured in the Customer Area. This prevents spoofed webhook injection. The combination means the middleware must manage two distinct credential stores: an OAuth2 token cache for commercetools and a static API key secret for Adyen, plus the HMAC key for inbound webhook validation.

Data Flow Diagram

Cart/Order OAuth2 Token Storefront / Checkout UI CT Auth Server OAuth2 CC Flow commercetools Payment API CT Subscriptions Event Bus Messages Middleware Orchestration Adyen Checkout POST /payments Adyen Mods Capture/Refund Adyen Webhooks HMAC Verified POST /payments captures/refunds Notifications Update Payment

Enterprise Use Cases

Use Case 1: Checkout Payment Authorisation

USE CASE 1
TRIGGER: OrderCreated / PaymentCreated
→ Adyen AUTHORISATION webhook → CT Payment state=Success
Real-Time Checkout Authorisation Flow
When a buyer places an order, the storefront creates a commercetools Payment object via POST /{projectKey}/payments with paymentMethodInfo.paymentInterface=Adyen and an initial Authorization Transaction in Pending state. The middleware picks up this event and calls Adyen POST /payments (or POST /sessions for Drop-in), mapping the commercetools amountPlanned to Adyen amount.value and amount.currency. Adyen returns a pspReference which is stored as a commercetools Payment interfaceId. The AUTHORISATION webhook subsequently fires; the middleware validates HMAC and calls POST /{projectKey}/payments/{ID} with an addTransaction action, setting the Authorization Transaction to Success or Failure. This state drives the Order confirmation workflow downstream.

Use Case 2: Delayed Manual Capture

USE CASE 2
TRIGGER: Order state=Confirmed (fulfillment)
→ Adyen CAPTURE webhook → CT Charge Transaction=Success
Fulfillment-Triggered Delayed Capture
For merchants who authorise at order placement but capture only at shipment, a commercetools Subscription listens for OrderStateChanged messages. When the Order state transitions to a “Ready to Ship” state, the middleware reads the commercetools Payment to retrieve the Adyen pspReference (stored as interfaceId) and calls POST /payments/{pspReference}/captures with the exact shipment amount. Partial captures are supported natively—useful for split shipments. Adyen fires a CAPTURE webhook; the middleware adds a Charge Transaction with state=Success to the commercetools Payment via addTransaction. If the capture fails, a CAPTURE_FAILED event is received and a Charge Transaction with state=Failure is recorded, alerting OMS workflows.

Use Case 3: Refund Orchestration

USE CASE 3
TRIGGER: Refund Transaction added to CT Payment
→ Adyen REFUND webhook → CT Refund Transaction=Success
Partial & Full Refund Processing
Customer service or OMS systems initiate refunds by adding a Refund Transaction in Initial state to the commercetools Payment via POST /{projectKey}/payments/{ID} with addTransaction. The commercetools API Extension (or Subscription) triggers the middleware, which calls Adyen POST /payments/{pspReference}/refunds with the refund amount.value. For pre-capture cancellations, POST /payments/{pspReference}/cancels is used instead. The Adyen REFUND webhook returns the outcome; the middleware transitions the commercetools Refund Transaction state from Pending to Success or Failure. Multiple partial refunds up to the full captured amount are fully supported by Adyen.

Use Case 4: Tokenised Recurring Payments

USE CASE 4
TRIGGER: RECURRING_CONTRACT webhook / Saved card checkout
→ Token stored on CT Customer → Frictionless re-purchase
Card Tokenisation & Stored Payment Methods
When a buyer opts to save their card, Adyen fires a RECURRING_CONTRACT webhook containing a recurringDetailReference (token). The middleware stores this reference in a commercetools Customer custom field (e.g. adyen-recurring-token) via POST /{projectKey}/customers/{ID} with setCustomField. On subsequent checkouts, the middleware calls Adyen GET /storedPaymentMethods to retrieve available tokens for the shopper reference, presents them in the UI, and charges the selected token via POST /payments with paymentMethod.storedPaymentMethodId. Token deletion is handled via DELETE /storedPaymentMethods/{storedPaymentMethodId} with a corresponding custom field clear on the CT Customer.

Use Case 5: Automated Chargeback Handling

USE CASE 5
TRIGGER: CHARGEBACK / NOTIFICATION_OF_CHARGEBACK webhook
→ CT Order flagged → Adyen dispute defended
Dispute & Chargeback Lifecycle Management
Adyen fires NOTIFICATION_OF_CHARGEBACK or CHARGEBACK webhooks when a card issuer raises a dispute. The middleware updates the related commercetools Order with a custom state (e.g. Disputed) and records a Chargeback Transaction on the Payment. An automated defense workflow then calls Adyen POST /retrieveApplicableDefenseReasons to determine valid counter-arguments, assembles shipping and fulfillment evidence from commercetools Order data, and submits via POST /supplyDefenseDocument followed by POST /defendDispute. Outcomes (CHARGEBACK_REVERSED, SECOND_CHARGEBACK) feed back into commercetools Order state transitions, providing a full audit trail in both systems.

Standard API Field Mapping

Note: Field names reflect canonical API schema identifiers. All endpoints verified against official documentation.

Entity commercetools Field Method Adyen Field Method Type
Payment Amount amountPlanned.centAmount GET amount.value POST Integer (minor units)
Currency amountPlanned.currencyCode GET amount.currency POST ISO 4217 String
Payment Interface ID interfaceId PATCH pspReference WEBHOOK String
Transaction Type transactions[].type (Authorization / Charge / Refund) POST eventCode (AUTHORISATION / CAPTURE / REFUND) WEBHOOK Enum
Transaction State transactions[].state (Pending / Success / Failure) PATCH success (true/false in webhook) WEBHOOK Boolean → Enum
Customer Reference customer.id (CT Customer UUID) GET shopperReference POST String
Customer Email customerEmail (on Order) GET shopperEmail POST String (email)
Billing Address billingAddress (Address object on Order) GET billingAddress POST Address Object
Merchant Order Reference id (CT Order UUID) or orderNumber GET merchantOrderReference / reference POST String
Stored Token Reference custom.fields.adyen-recurring-token (Customer) PATCH recurringDetailReference / storedPaymentMethodId WEBHOOK String
Refund Amount transactions[].amount.centAmount (Refund type) GET amount.value in POST /payments/{pspReference}/refunds POST Integer (minor units)
Payment Method paymentMethodInfo.method GET paymentMethod.type POST String

Limitations & Rate Limits

Risk Advisory: Validate all rate limits with vendor TAMs before production go-live.

commercetools Rate Limits

Constraint Limit Detail Mitigation
API Requests per second (default) DATA_UNAVAILABLE Rate limits are tier-based and contractually defined; not publicly documented in the API reference. Use exponential backoff; request dedicated limits from commercetools TAM for high-volume integrations.
Subscription Message Delivery At-least-once commercetools Subscriptions guarantee at-least-once delivery; duplicate messages are possible. Implement idempotency in middleware using the commercetools Message id as a deduplication key.
Optimistic Concurrency Version-based All write operations require the current resource version; concurrent updates will fail with 409 Conflict. Implement retry logic with fresh GET before each update; avoid parallel writes to the same Payment resource.
Query Result Set Size 500 per page (default 20) Maximum limit parameter is 500; use offset or cursor-based pagination for large sets. Use Order Search or Message subscriptions instead of polling large query sets.

Adyen Rate Limits

Constraint Limit Detail Mitigation
Checkout API Requests DATA_UNAVAILABLE Adyen does not publish specific rate limits in the public API Explorer; limits are defined per merchant account contract. Implement request queuing and exponential backoff; contact Adyen support for merchant-specific thresholds.
Webhook Delivery Retries Up to 24 hours Adyen retries webhook delivery if the endpoint does not respond with HTTP 200 within the timeout window. Ensure webhook endpoint responds within 3 seconds; offload processing to async queue before acknowledging.
Test Environment Restrictions Test cards only Adyen test environment only accepts test card numbers; live credentials and endpoints differ from test. Maintain separate credential sets and endpoint URLs per environment via configuration management.
Idempotency (captures/refunds) Reference-based Duplicate capture or refund calls with the same reference may result in double-charges if not guarded. Use a deterministic reference derived from the CT Payment id + Transaction id for all modification calls.

Critical Engineering Constraints


Optimistic Concurrency on CT Payments: commercetools rejects any Payment update that does not supply the current version number. Under high-concurrency webhook storms (e.g. simultaneous CAPTURE and AUTHORISATION events for the same Payment), middleware must implement a read-then-write pattern with version-aware retry logic or risk repeated 409 failures that leave Payment state in Pending.

HMAC Validation is Non-Optional: Adyen webhook endpoints exposed to the internet must validate the hmacSignature in every notification payload. Skipping this step exposes the integration to spoofed payment confirmations, which could result in order fulfilment without actual payment receipt.

Minor Currency Unit Mapping: Both platforms express monetary amounts in minor currency units (e.g. cents for USD/EUR), but the middleware must be aware of zero-decimal currencies (e.g. JPY) where centAmount=100 maps to 100 JPY, not 1 JPY. Incorrect mapping will result in mis-charged amounts that may be unrecoverable without manual intervention.

Webhook Ordering Not Guaranteed: Adyen delivers webhook events asynchronously and does not guarantee strict ordering. CAPTURE webhooks may arrive before AUTHORISATION webhooks in rare network conditions. Middleware state machines must handle out-of-order events without corrupting the commercetools Payment Transaction chain.

OAuth2 Token Lifecycle Management: commercetools access tokens have a fixed TTL. Long-running middleware processes (e.g. batch refund jobs) must proactively refresh tokens before expiry. Using an expired token results in 401 errors that can cause silent payment update failures if not properly caught and retried.

Official Documentation


COMMERCETOOLS
HTTP API — Composable Commerce Full API Reference
VIEW DOCS →


COMMERCETOOLS
Payments API — Payment Resource, Transactions & State Management
VIEW DOCS →


COMMERCETOOLS
Subscriptions — Event-Driven Message Delivery to SQS, SNS, Pub/Sub
VIEW DOCS →


ADYEN
Checkout API v71 — Sessions, Payments, Captures, Refunds & Cancels
VIEW DOCS →


ADYEN
Webhooks API — Standard Notifications, Dispute & Tokenisation Events
VIEW DOCS →


ADYEN
Disputes API v30 — Defend, Accept & Supply Documents for Chargebacks
VIEW DOCS →