Skip to content

New: AI agent integration via Model Context Protocol (MCP).Learn more

Payment architecture

The checkout service orchestrates payment processing by coordinating between payment provider services (Stripe, Adyen, Mollie, PayNL, etc.) and commercetools. Each payment provider is a standalone service that handles communication with its PSP. The provider only updates the Payment object and its transactions. Order-level actions (confirming an order, handling cancellations) are handled by the checkout service through event subscriptions.

sequenceDiagram
    actor CU as Customer
    participant WE as Website
    participant CO as Checkout
    participant PS as PSP service
    participant CT as commercetools
    participant PSP as PSP
    participant BANK as Bank

    Note over CU,BANK: Start payment flow
    CU->>WE: Start payment step

    activate WE
    WE ->> CO: createPayment
    activate CO
    CO ->> CT: get order
    activate CT
    CT -->> CO: order data
    CO ->> CT: create Payment on order
    activate CT
    CO ->> PS: create transaction
    activate PS
    PS ->> PSP: create transaction
    activate PSP
    PSP -->> PS: transaction object
    deactivate PSP
    PS ->> CT: create Transaction on payment
    deactivate CT
    deactivate CT
    PS -->> CO: transaction result
    deactivate PS
    CO -->> WE: return payment redirect URL
    deactivate CO

    WE-->>CU: Redirect customer to PSP
    activate PSP
    CU->>PSP: Pay order at PSP
    PSP->>BANK: redirect to bank
    activate BANK
    BANK ->> BANK: pay/cancel/else
    BANK-->>PSP: return payment result
    deactivate BANK
    PSP-->>WE: Return to returnURL
    deactivate PSP

    WE->>CO: Update order payment status
    activate CO
    CO->>CT: Fetch order by transaction ID
    activate CT
    CT-->>CO: Return order
    deactivate CT
    CO->>PS: Fetch transaction status for order
    activate PS
    PS->>PSP: Fetch transaction status
    activate PSP
    PSP-->>PS: Return transaction status
    deactivate PSP
    PS->>CT: Update transaction status
    activate CT
    PS-->>CO: Return transaction status
    deactivate PS
    deactivate CT
    CO->>CT: Fetch update order
    activate CT
    CT-->>CO: Return updated order
    deactivate CT
    CO-->>WE: Return order with payment status
    deactivate CO
    WE->>CU: Show confirmation page

    deactivate WE

When a payment is needed, the frontend calls the createPayment mutation. The checkout service then:

  1. Fetches the order from commercetools
  2. Creates a Payment object on the order with the selected method and payment interface
  3. Delegates to the appropriate PSP service to start a transaction
  4. Returns a redirect URL so the customer can complete payment

The Payment object stores the selected method in paymentMethodInfo.method and the provider identifier in paymentMethodInfo.paymentInterface.

The checkout service manages payment state transitions through commercetools state machines. Payment providers transition the Payment to one of these states:

State Key Environment variable override
Initial PaymentInitial PAYMENT_STATE_KEY_INITIAL
Pending PaymentPending PAYMENT_STATE_KEY_PENDING
Success PaymentSuccess PAYMENT_STATE_KEY_SUCCESS
Cancelled PaymentCancelled PAYMENT_STATE_KEY_CANCELLED
Failure PaymentFailure PAYMENT_STATE_KEY_FAILURE

These state objects are defined in the checkout service’s Terraform configuration and looked up by key at runtime. You can override the default keys through environment variables if your project uses different naming.

When a payment state changes, commercetools emits a PaymentStatusStateTransition message. The checkout service subscribes to these messages and updates the order accordingly. For example, when all payments on an order reach PaymentSuccess, the checkout service transitions the order’s payment state to paid.

This event-driven approach means the checkout service reacts to payment outcomes asynchronously rather than polling for status changes. See Messaging & events for how event subscriptions work across all services.

A payment provider exposes the following API endpoints:

POST /payment-methods: return the payment methods available for the given cart. The cart ID and other context are passed in the request body.

POST /create: create a payment transaction. This starts the payment flow and returns a redirect URL for the customer to complete payment at the PSP.

POST /push (webhook): receive asynchronous payment status updates from the PSP. This endpoint handles webhook callbacks and updates the transaction status in commercetools. See REST endpoints & webhooks for how each provider verifies webhook authenticity.

A payment provider may also expose:

GET /redirect: handle customer redirects back from the PSP after completing payment.

POST /validate-apple-pay-session: validate an Apple Pay merchant session for Apple Pay payments.

The payment API contract is defined as TypeBox schemas in the @evolve-framework/commercetools package (packages/commercetools/src/payments/schema.ts). The two primary endpoints and their types are documented below.

Starts a payment transaction and returns a redirect URL for the customer to complete payment at the PSP.

Request body: TransactionRequest

Field Type Required Description
amount Price yes Transaction amount
customer object yes { ipAddress: string } - IPv4 or IPv6
locale string yes e.g. en-GB, nl-NL
targetId string (UUID) yes commercetools cart or order ID
targetType string yes cart or order
paymentId string (UUID) yes commercetools payment ID
paymentMethod string yes Payment method code
paymentMethodArgs object yes Provider-specific arguments
successUrl string (URL) yes Redirect after successful payment
failureUrl string (URL) yes Redirect after failed payment

Response body: TransactionResponse

Field Type Description
status string Transaction status
payload.id string (UUID) Transaction identifier
payload.redirectURL string (URL) Customer redirect URL

Returns the payment methods available for the given context (cart, locale, country).

Request body: PaymentMethodArgs

Field Type Required Description
targetId string (UUID) no Cart or order to check methods for
targetType string yes cart or order
currency string yes e.g. EUR, USD
country string yes e.g. NL, DE
locale string yes e.g. en-GB, nl-NL
device string yes web, ios, or android

Response body: PaymentMethod[]

Field Type Description
id string Method identifier
localizedName string Display name for the requested locale
provider string PSP provider key
issuers array Sub-options (e.g. iDEAL banks), each with id and name

Price

Field Type Description
currency string ISO 4217 currency code
centAmount number (integer format) Amount in the smallest currency unit