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
https://auth.{region}.commercetools.com/oauth/token endpoint using client_credentials flow. Tokens are scoped per API client and carry TTLs requiring proactive refresh./{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./{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.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.POST /defendDispute, POST /acceptDispute, and POST /supplyDefenseDocument. Feeds dispute webhook events back to commercetools Order resource for automated chargeback state tracking.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
Enterprise Use Cases
Use Case 1: Checkout Payment Authorisation
Use Case 2: Delayed Manual Capture
Use Case 3: Refund Orchestration
Use Case 4: Tokenised Recurring Payments
Use Case 5: Automated Chargeback Handling
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 →