Stripe payments integration with commercetools Connect
This repository provides a commercetools connect integration for Stripe payment, enabling a drop-in experience through the Stripe Payment Element and supporting webhook handling, payment intents, and checkout configuration.
STRIPE_SUBSCRIPTION_PRICE_SYNC_ENABLED environment variable. Learn more.stripeConnector_ prefix for better organization and consistency. The system automatically handles the transformation between prefixed attribute names and internal field names. Learn more.updateSubscription method provides seamless subscription management while maintaining data consistency. Learn more.requires_action and payment_failed with structured error objects for better debugging.STRIPE_ENABLE_MULTI_OPERATIONS=true. Requires multicapture enabled in your Stripe account and manual capture mode. Learn more.stripeConfig option that allows frontend to override backend configuration for Stripe Elements (appearance, layout, billing address) and PaymentIntent (payment method options). This enables per-implementation customization without backend changes. See Detailscart.taxedPrice is present), the Express Checkout order summary displays a net subtotal, a tax line, and the shipping line — preventing duplicate tax display. The shipping line also shows the actual shipping method name instead of a generic label.The connector implements a sophisticated price synchronization system that maintains consistency between Stripe subscriptions and commercetools product prices. This system operates on the principle of Stripe as the source of truth for products and commercetools as the source of truth for prices.
Automatic Mode (STRIPE_SUBSCRIPTION_PRICE_SYNC_ENABLED=true):
invoice.upcoming webhookStandard Mode (STRIPE_SUBSCRIPTION_PRICE_SYNC_ENABLED=false):
createOrder methodFor detailed configuration and implementation details, see Subscription Price Synchronization.
Create an API client responsible for payment management in a composable commerce project. The API client details are input as environment variables/ configuration for connect, such as CTP_PROJECT_KEY, CTP_CLIENT_ID, and CTP_CLIENT_SECRET. Please read Deployment Configuration for details.
In addition, please make sure the API client has enough scope to manage Payment. For details, please refer to Running Application
Configure various URLs from the commercetools platform, so that the connect application can handle the session and authentication process for endpoints.
Their values are input for environment variables/configurations for connecting, with variable names CTP_API_URL, CTP_AUTH_URL, CTP_SESSION_URL, and CTP_CHECKOUT_URL.
Configure Stripe secret and public keys so the Connect application can handle endpoint session and authentication processes. Their values are taken as input as environment variables/ configuration for Connect, with variable names STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, and STRIPE_WEBHOOK_SIGNING_SECRET.
If you want to create a Restricted key to add in the STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY, the minimum permissions needed are:
The connect-payment-integration-stripe contains two modules:
connect-payment-sdk based on webhook events.Regarding the development of a processor or enabler module, please refer to the following documentation:

The Enabler component is tasked with rendering the Stripe Payment Element or Express Checkout, providing a seamless payment experience for users. The diagram below illustrates the workflow for initializing these payment components:

Once the payment component is set up, the connector orchestrates various payment flows based on the user’s context—such as logged-in customers, guest checkouts, and subscriptions (with or without a SetupIntent). The following sequence diagrams break down these scenarios:
Standard Payment Flow:

Subscription with Invoice:

Subscription without Invoice:

Each diagram details the interactions and steps involved in processing the respective payment type.
Subscription payment and order handling was corrected so that each recurring cycle produces exactly one commercetools payment/order, and the first cycle creates its order reliably.
invoice.paid is the single source of truth for subscription payments. Stripe also emits charge.succeeded / payment_intent.succeeded for the same subscription invoice, but the webhook route now ignores those via isFromSubscriptionInvoice() to prevent duplicate CT payments/orders. processSubscriptionEventCharged is deprecated and no longer wired.in_…) rather than the PaymentIntent id, and recurring mixed-cart order composition was fixed.price.discounted ?? price.value, not the list price. (Cart-level coupon duration mapping remains a known gap — see context/known-issues.md KI-016.)npm audit fix.See docs/CHANGELOG.md and context/business-rules/recurring-billing.md (Rule 4) for details.
The payment processing system has been significantly enhanced with advanced multicapture and refund capabilities. These features are opt-in and disabled by default to ensure backward compatibility.
STRIPE_ENABLE_MULTI_OPERATIONS=true (default: false)STRIPE_CAPTURE_METHOD=manualcharge.updated and charge.refunded events. charge.refunded is registered by post-deploy; charge.updated is not — add it to the endpoint by hand in the Stripe Dashboard, or multicapture events never arrivecharge.updated and charge.refunded events that only process when feature is enabledfinal_capture handlingCHARGE__UPDATED events and enhanced refund processingThe subscription service has undergone major architectural improvements with comprehensive testing enhancements:
price-client.ts service for enhanced product price management and retrievalgetProductById(): Retrieves products with expanded price informationgetProductMasterPrice(): Gets current price from product master variantgetSubscriptionShippingPriceId(): Retrieves or creates shipping price IDsgetStripeShippingPriceByMetadata(): Searches for existing shipping pricescreateStripeShippingPrice(): Creates new Stripe shipping pricesFor detailed information about these improvements, see the Processor Documentation.
For technical implementation details, see the Subscription Shipping Fee Integration Guide.
For enabler and payment service improvements, see the Enabler Improvements Guide.
The following webhooks are registered by the post-deploy script (processor/src/connectors/actions.ts,
enabled_events) and routed in processor/src/routes/stripe-payment.route.ts. This list must stay in
sync with enabled_events — a handler that exists without its event registered never fires.
One-time payments
amount matches the cart’s current total, amount_received equals amount, and the currency matches — the backstop against a cart edited while an async payment settled (see ACH below). On a mismatch it logs an error and returns; the Charge: Success already written leaves a paid-without-order state for manual reconciliation. An already-Ordered cart is skipped idempotently.processSubscriptionEventLateReturn — see below.next_action.type = display_bank_transfer_instructions) writes one Authorization: Pending for the full PaymentIntent amount and freezes the cart; the order is created only when funds arrive. An ACH micro-deposit (next_action.type = verify_with_microdeposits) freezes the cart so it cannot be edited during the multi-day verification window, and writes no transaction. Everything else — card 3DS, Boleto — keeps the log-only path. A subscription-invoice event logs and stops.payment_intent.succeeded and Failure on payment_intent.payment_failed / payment_intent.canceled. Guarded against out-of-order and duplicate events.isFromSubscriptionInvoice, keyed on the connector’s own subscription_id metadata); recurring subscription payments are recorded solely from invoice.paid to avoid duplicate commercetools payments/orders.enabled_events, so Stripe never delivers it and the handler does not currently run. When wired, it handles multicapture scenarios by creating Charge: Success transactions with incremental captured amounts, and only when STRIPE_ENABLE_MULTI_OPERATIONS=true. Registering it is an open item — see context/known-issues.md.Refunds
STRIPE_ENABLE_MULTI_OPERATIONS=true; gracefully skipped when disabled.charge.refunded fires when the Refund object is created, which on a delayed rail is not the same as succeeded — a bank-transfer refund is created pending. These two events write a correcting Refund: Failure when Stripe later rejects the refund, which previously stayed recorded as successful forever.Bank transfer cash balance
error level for funding_reversed and adjusted_for_overdraft and at info otherwise. The raw event is never logged: it carries sender_name, iban_last4, account_number_last4 and sort_code. This is the only signal for a bank-transfer clawback; wire it to an alerting channel.Subscriptions
in_…). This is also what settles an ACH Charge: Pending written at confirm.ct_payment_id metadata. Idempotent, skips a cart that is not frozen, and changes no payment or order state (retrying with another method happens in Stripe). The cart stays frozen through the Smart Retry window; only this event releases it.On
invoice.paidandinvoice.payment_failed, a commercetools write that fails with a transient
error (ConcurrentModification/409, 429, 502, 503,ETIMEDOUT,ECONNRESET) is rethrown so the webhook
responds non-2xx and Stripe redelivers. Permanent errors are logged and swallowed, so a bad credential
does not turn into a days-long retry storm.
us_bank_account)ACH is enabled from the Stripe Dashboard; there is no connector configuration for it. It is
asynchronous — the debit settles in ~2–4 business days and can still fail afterwards — which is what
drives the webhook behavior above.
POST /subscription/confirm reads the real PaymentIntent status rather thansucceeded/requires_capture writes Charge: Success, and processing writesinvoice.paid later promotes to Success and invoice.payment_failed turnsrequires_action) is not supported on subscriptions: the confirm throws.requires_action, and order creation is gated on the amount actually collected.payment_intent.payment_failed but does not re-fire invoice.payment_failed, sopaymentStatus.interfaceCode = 'ach_late_return' and leaves the financial correction to the Stripe Dashboard — no transaction, orderBefore installing the connector, you must create a Stripe account and obtain the necessary credentials. The Stripe account is required to process payments and manage transactions. Sign up for a Stripe account at Stripe. Once you have an account, you must set up the following configurations in your environment variables or configuration files. Before installing the connector, a webhook endpoint in Stripe must be created (using a dummy URL). Retrieve the ID and Signing Secret from the Stripe Console. The Webhook Endpoint is update during the post-deploy script after the deployed connector. It’s important to set the correct values in the variables so the events are sent to the connector and can be accepted. The following Stripe account credentials and configurations are required:
automatic: Stripe automatically captures funds when the customer authorizes the Payment.automatic_async: (Default) Stripe asynchronously captures funds when the customer authorizes the Payment. Recommended over capture_method=automatic due to improved latency. Read the integration guide for more information.manual: Places a hold on the funds when the customer authorizes the Payment but doesn’t capture the funds until later. (Not all payment methods support this.) Required for multicapture support - must be set to manual when STRIPE_ENABLE_MULTI_OPERATIONS=true.//stringified, eg.
{"theme":"night","labels":"floating"}
//stringified, eg.
{"theme":"night","labels":"floating"}
//stringified eg.
{"type":"accordion","defaultCollapsed":false,"radios":true, "spacedAccordionItems":false}
//stringified, eg.
{"payment_method_save_usage":"off_session","payment_method_redisplay_limit":10}
auto. More information can be found here.2025-12-15.clover). Allows merchants to pin to specific Stripe API versions.These commercetools-specific variables are essential for the connector to properly authenticate and communicate with the commercetools platform.
We must create the connector on the commercetools connect marketplace, enable the checkout feature in the merchant center, and select the payment connector as the drop-in payment method on the checkout configuration page. Users create an API client responsible for payment management in a composable commerce project. The API client’s details are input as environment variables/ configuration for connecting, such as CTP_PROJECT_KEY, CTP_CLIENT_ID, and CTP_CLIENT_SECRET.
CTP_API_URL, CTP_AUTH_URL, CTP_SESSION_URL, and CTP_CHECKOUT_URL.Note: To use the Stripe Composable Connector installed, you must call the enabler module from the installed connector URL. To find more information about how to use the enabler module, please refer to the Enabler documentation.
This section explains how to integrate the Stripe Composable connector with commercetools. First, load the Stripe Enabler using the URL provided by the connector information page. Then initialize a payment component by creating a new Enabler instance.
The Enabler constructor accepts the following options:
const enabler = new Enabler({
processorUrl: string, // Backend processor URL (required)
sessionId: string, // Commercetools session ID (required)
locale?: string, // Optional locale for the payment
onActionRequired?: () => Promise<void>, // Optional callback when action is required
onComplete?: (result) => void, // Callback when payment is completed
onError?: (error) => void, // Callback for error handling
paymentElementType?: string, // Component type: 'paymentElement' or 'expressCheckout'
stripeCustomerId?: string, // Optional Stripe customer ID
stripeConfig?: { // Optional frontend configuration override
elements?: {
appearance?: Appearance, // Overrides STRIPE_APPEARANCE_PAYMENT_ELEMENT or STRIPE_APPEARANCE_EXPRESS_CHECKOUT
layout?: LayoutObject, // Overrides STRIPE_LAYOUT
collectBillingAddress?: 'auto' | 'never' | 'if_required' // Overrides STRIPE_COLLECT_BILLING_ADDRESS
},
paymentIntent?: {
paymentMethodOptions?: Record<string, Record<string, unknown>> // Payment method-specific options (e.g., PIX expiration)
}
}
});
The stripeConfig option allows you to override backend configuration from the frontend, providing per-implementation customization without requiring backend changes. This is particularly useful for:
Note: Payment method options can also be specified via the POST /payments endpoint by including paymentMethodOptions in the request body. The stripeConfig.paymentIntent.paymentMethodOptions takes precedence when both are provided. For detailed API documentation, see Processor Documentation.
Example with stripeConfig:
const enabler = new Enabler({
processorUrl: COMMERCETOOLS_PROCESSOR_URL,
sessionId: SESSION_ID,
paymentElementType: 'paymentElement',
onComplete: ({ isSuccess, paymentReference, paymentIntent }) => {
console.log('Payment completed', { isSuccess, paymentReference, paymentIntent });
},
onError: (err) => {
console.error('Payment error', err);
},
stripeConfig: {
elements: {
appearance: {
theme: 'night',
variables: {
colorPrimary: '#7c3aed',
},
},
layout: {
type: 'accordion',
defaultCollapsed: false,
},
collectBillingAddress: 'never',
},
paymentIntent: {
paymentMethodOptions: {
pix: {
expires_after_seconds: 3600,
},
},
},
},
});
const builder = await enabler.createDropinBuilder('embedded');
const component = await builder.build({
showPayButton: !builder.componentHasSubmit,
});
component.mount('#payment');
The integration requires a few steps: create the enabler instance with required configuration (including processor URL and callbacks), build a component using createDropinBuilder, and mount it to a DOM element. The component handles payment processing while maintaining security standards. You’ll need to replace placeholder variables with your actual application configuration values to complete the integration.
For detailed implementation instructions and additional code examples, please refer to the Enabler documentation.
By default all Express Checkout components are created with ‘shippingAddressRequired’ and ‘billingAddressRequired’ set to true. This means that the Express Checkout component can update the shipping methods and the address information in the cart. You can find the information of the methods responsible for updating the shipping methods in the Processor Documentation.
The connector implements cart freezing to protect cart integrity during payment flows. Carts are automatically frozen after PaymentIntent or Subscription creation to prevent modifications during payment processing. During Express Checkout operations, frozen carts are temporarily unfrozen to allow shipping information updates, then automatically re-frozen to maintain protection.
Key Behaviors:
This ensures that Express Checkout can update shipping information even when the cart is protected during the payment flow, while maintaining cart integrity throughout the checkout process.
Apple Pay integration requires three key elements:
.well-known directory that redirects to {COMMERCETOOLS_PROCESSOR_URL}/applePayConfig to satisfy Apple’s domain verification requirementsFor detailed implementation instructions, see the Apple Pay considerations in the Enabler documentation.
Google Pay implementation requires:
For complete implementation details, refer to the Google Pay considerations in the Enabler documentation.
It needs to be published to deploy your customized connector application on commercetools Connect. For details, please refer to documentation about commercetools Connect
In addition, the tax integration connector template has a folder structure, as listed below, to support Connect.
├── enabler
│ ├── src
│ ├── test
│ └── package.json
├── processor
│ ├── src
│ ├── test
│ └── package.json
└── connect.yaml
The connect deployment configuration specifie in connect.yaml, the information needed to publish the application. Following is the deployment configuration used by the Enabler and Processor modules
deployAs:
- name: enabler
applicationType: assets
- name: processor
applicationType: service
endpoint: /
scripts:
postDeploy: npm install && npm run connector:post-deploy
preUndeploy: npm install && npm run connector:pre-undeploy
configuration:
standardConfiguration:
- key: CTP_PROJECT_KEY
description: commercetools project key
required: true
- key: CTP_AUTH_URL
description: commercetools Auth URL (example - https://auth.europe-west1.gcp.commercetools.com).
required: true
default: https://auth.europe-west1.gcp.commercetools.com
- key: CTP_API_URL
description: commercetools API URL (example - https://api.europe-west1.gcp.commercetools.com).
required: true
default: https://api.europe-west1.gcp.commercetools.com
- key: CTP_SESSION_URL
description: Session API URL (example - https://session.europe-west1.gcp.commercetools.com).
required: true
default: https://session.europe-west1.gcp.commercetools.com
- key: CTP_CHECKOUT_URL
description: Checkout API URL (example - https://checkout.europe-west1.gcp.commercetools.com).
required: true
- key: CTP_JWKS_URL
description: JWKs url (example - https://mc-api.europe-west1.gcp.commercetools.com/.well-known/jwks.json)
required: true
default: https://mc-api.europe-west1.gcp.commercetools.com/.well-known/jwks.json
- key: CTP_JWT_ISSUER
description: JWT Issuer for jwt validation (example - https://mc-api.europe-west1.gcp.commercetools.com)
required: true
default: https://mc-api.europe-west1.gcp.commercetools.com
- key: STRIPE_CAPTURE_METHOD
description: Stripe capture method (example - manual|automatic).
default: automatic
- key: STRIPE_PAYMENT_FLOW
description: 'Optional. Stripe Elements initialization strategy - deferred|pi_first. Unset means deferred. pi_first creates the PaymentIntent before the Element mounts and initializes Elements with its clientSecret, which bank transfers (customer_balance) and BLIK need. STILL DO NOT SET pi_first - opening the payment page alone creates a PaymentIntent and a commercetools Payment with no deterministic idempotency key, so a remount orphans the previous pair, and an unfunded bank transfer makes the cart read as paid in full. An invalid value does not abort startup - it is reported to the deploy log and falls back to deferred, which also disables bank transfers and BLIK. Per-cart override - flowType in STRIPE_PAYMENT_BEHAVIOR_RULES.'
- key: STRIPE_PAYMENT_BEHAVIOR_RULES
description: 'Optional JSON map of cart country or commercetools store key to payment behavior overrides. Contains exceptions only - the flat variables are always the default and there is no wildcard key. Each rule may set flowType, captureMethod, setupFutureUsage and euBankTransferCountry (DE|FR|IE|NL). Malformed JSON or a rule that is not an object aborts startup; an unknown field or an invalid value does not - it is reported to the deploy log and ignored. Example - {"DE":{"captureMethod":"automatic","euBankTransferCountry":"DE"},"MX":{"captureMethod":"manual"}}'
- key: STRIPE_WEBHOOK_ID
description: Stripe unique identifier for the Webhook Endpoints (example - we_*****).
required: true
- key: STRIPE_APPEARANCE_PAYMENT_ELEMENT
description: Stripe Appearance for Payment Element (example - {"theme":"stripe","variables":{"colorPrimary":"\#0570DE","colorBackground":"\#FFFFFF","colorText":"\#30313D","colorDanger":"\#DF1B41","fontFamily":"Ideal Sans,system-ui,sansserif","spacingUnit":"2px","borderRadius":"4px"}}).
- key: STRIPE_APPEARANCE_EXPRESS_CHECKOUT
description: Stripe Appearance for Express Checkout (example - {"theme":"stripe","variables":{"colorPrimary":"\#0570DE","colorBackground":"\#FFFFFF","colorText":"\#30313D","colorDanger":"\#DF1B41","fontFamily":"Ideal Sans,system-ui,sansserif","spacingUnit":"2px","borderRadius":"4px"}}).
- key: STRIPE_LAYOUT
description: Stripe Layout for Payment Element (example - {"type":"accordion","defaultCollapsed":false,"radios":true,"spacedAccordionItems":false} ).
default: '{"type":"tabs","defaultCollapsed":false}'
- key: STRIPE_PUBLISHABLE_KEY
description: Stripe Publishable Key
required: true
- key: STRIPE_APPLE_PAY_WELL_KNOWN
description: Domain association file from Stripe. (example - https://stripe.com/files/apple-pay/apple-developer-merchantid-domain-association)
- key: STRIPE_SAVED_PAYMENT_METHODS_CONFIG
description: Stripe configuration for saved payment methods (example - {"payment_method_save":"enabled","payment_method_save_usage":"off_session","payment_method_redisplay":"enabled","payment_method_redisplay_limit":10}).
default: '{"payment_method_save":"disabled"}'
- key: MERCHANT_RETURN_URL
description: Merchant return URL
required: true
- key: STRIPE_COLLECT_BILLING_ADDRESS
description: Stripe collect billing address information in Payment Element (example - 'auto' | 'never' | 'if_required').
default: 'auto'
required: true
- key: STRIPE_SUBSCRIPTION_PAYMENT_HANDLING
description: Subscription payment handling strategy (createOrder|addPaymentToOrder).
default: createOrder
- key: STRIPE_SUBSCRIPTION_PRICE_SYNC_ENABLED
description: Enable automatic price synchronization for subscriptions (true|false).
default: false
- key: STRIPE_ENABLE_MULTI_OPERATIONS
description: Enable multicapture and multirefund support (true|false). When enabled, allows multiple partial captures and multiple refunds on payments. IMPORTANT - Requires multicapture to be enabled in your Stripe account.
default: 'false'
- key: STRIPE_API_VERSION
description: Stripe API version to use (example - 2025-12-15.clover).
default: '2025-12-15.clover'
- key: CT_CUSTOM_TYPE_LAUNCHPAD_PURCHASE_ORDER_KEY
description: Custom type key for launchpad purchase order number.
required: true
default: 'payment-launchpad-purchase-order'
- key: CT_CUSTOM_TYPE_STRIPE_CUSTOMER_KEY
description: Custom type key for Stripe customer ID.
required: true
default: 'payment-connector-stripe-customer-id'
- key: CT_CUSTOM_TYPE_SUBSCRIPTION_LINE_ITEM_KEY
description: Custom type key for subscription line item.
required: true
default: 'payment-connector-subscription-line-item-type'
- key: CT_PRODUCT_TYPE_SUBSCRIPTION_KEY
description: Product type key for subscription information.
required: true
default: 'payment-connector-subscription-information'
securedConfiguration:
- key: CTP_CLIENT_SECRET
description: commercetools client secret.
required: true
- key: CTP_CLIENT_ID
description: commercetools client ID with manage_payments, manage_orders, view_sessions, view_api_clients, manage_checkout_payment_intents, introspect_oauth_tokens, manage_types and view_types scopes
required: true
- key: STRIPE_SECRET_KEY
description: Stripe secret key (example - sk_*****).
required: true
- key: STRIPE_WEBHOOK_SIGNING_SECRET
description: Stripe Webhook signing secret (example - whsec_*****).
required: true
Here, you can see the details about various variables in the configuration
CTP_PROJECT_KEY: The key to the commercetools composable commerce project.CTP_SCOPE: The scope constrains the endpoints to which the commercetools client has access and the read/write access right to an endpoint.CTP_AUTH_URL: The URL for authentication in the commercetools platform. Generate the OAuth 2.0 token required in every API call to commercetools composable commerce. The default value is https://auth.europe-west1.gcp.commercetools.com. For details, please refer to the documentation here.CTP_API_URL: The URL for commercetools composable commerce API. The default value is https://api.europe-west1.gcp.commercetools.com.CTP_SESSION_URL: The URL for session creation in the commercetools platform. Connectors rely on the session created to share information between the enabler and processor. The default value is https://session.europe-west1.gcp.commercetools.com.CTP_CHECKOUT_URL: The URL for commercetools Checkout API. Required for checkout-related operations. Example: https://checkout.europe-west1.gcp.commercetools.com.CTP_JWKS_URL: The JSON Web Key Set URL. Default value is https://mc-api.europe-west1.gcp.commercetools.com/.well-known/jwks.jsonCTP_JWT_ISSUER: The issuer inside JSON Web Token, required in the JWT validation process. The default value is https://mc-api.europe-west1.gcp.commercetools.comSTRIPE_CAPTURE_METHOD: Stripe capture method (manual or automatic), default value: automatic.STRIPE_APPEARANCE_PAYMENT_ELEMENT: Stripe Elements supports visual customization, which allows you to match the design of your site with the appearance option. This value has the specific appearance of the Payment Element component. The value needs to be a valid stringified JSON. More information about the properties can be found here.STRIPE_APPEARANCE_EXPRESS_CHECKOUT: Stripe Elements supports visual customization, which allows you to match the design of your site with the appearance option. This value has the specific appearance of the Express Checkout component.STRIPE_LAYOUT: Stripe allows you to customize the Payment Element’s Layout to fit your checkout flow (accordions or tabs). Default value is {"type":"tabs","defaultCollapsed":false}STRIPE_APPLE_PAY_WELL_KNOWN: Domain association file from Stripe. We can find more information in this link.CTP_CLIENT_SECRET: The client secret of commercetools composable commerce user account. It is used in commercetools for clients to communicate with commercetools composable commerce via SDK.CTP_CLIENT_ID: The client ID of your commercetools composable commerce user account. It is used in commercetools for clients to communicate with commercetools composable commerce via SDK. Expected scopes are: manage_payments manage_orders view_sessions view_api_clients manage_checkout_payment_intents introspect_oauth_tokens manage_types view_types.STRIPE_SECRET_KEY: Stripe authenticates your API requests using your account’s API keysSTRIPE_PUBLISHABLE_KEY: Stripe authenticates your frontend requests using your account’s Publishable keysSTRIPE_WEBHOOK_ID: Stripe unique identifier for the Webhook EndpointsSTRIPE_WEBHOOK_SIGNING_SECRET: Stripe Secret key to verify webhook signatures using the official libraries. This key is created in the Stripe dashboard Webhook.MERCHANT_RETURN_URL: Merchant return URL used on the confirmPayment return_url parameter. The Buy Now Pay Later payment methods will send the Stripe payment_intent in the URL; the Merchant will need to retrieve the payment intent and look for the metadata ct_payment_id to be added in the commercetools Checkout SDK paymentReference.STRIPE_SAVED_PAYMENT_METHODS_CONFIG: Stripe allows you to configure the saved payment methods in the Payment Element, refer to docs. This feature is disabled by default. To enable it, you need to add the expected customer session object. Default value is {"payment_method_save":"disabled"}STRIPE_COLLECT_BILLING_ADDRESS: Stripe allows you to collect the shipping address in the Payment Element. If you want to collect the shipping address, you need to set this value to never. The default value is auto. More information can be found here.STRIPE_SUBSCRIPTION_PAYMENT_HANDLING: Defines the strategy for handling subscription payments. Options are:
createOrder (creates a new order for each subscription payment - default)addPaymentToOrder (adds payment to existing order)STRIPE_SUBSCRIPTION_PRICE_SYNC_ENABLED: Enables automatic price synchronization for subscriptions.
true: Subscription prices are automatically synchronized with current commercetools product prices before each invoice is created via invoice.upcoming webhook events (price changes take effect in current billing cycle)false (default): Price updates happen after invoice payment via createOrder method (price changes take effect in next billing cycle)STRIPE_PAYMENT_FLOW: Stripe Elements initialization strategy — deferred (default) or pi_first, case-sensitive. deferred creates Elements with { mode, amount, currency } and the PaymentIntent at submit time. pi_first creates the PaymentIntent before the Element mounts and initializes Elements with its clientSecret, which bank transfers (customer_balance) and BLIK require — they cannot render in the deferred flow at all.
pi_first yet. Opening the payment page alone creates a PaymentIntent and a commercetools Payment, and creation has no deterministic idempotency key, so any remount orphans the previous pair. An unfunded bank transfer also makes the cart read as paid in full, so a shopper reloading the page gets an error instead of an “awaiting your transfer” state.deferred, which also silently disables bank transfers and BLIK. Check that log after changing it.pi_first the Element shows and saves no saved payment methods: Stripe’s clientSecret-based Elements options cannot carry setupFutureUsage, and customerOptions is deliberately omitted.flowType in STRIPE_PAYMENT_BEHAVIOR_RULES.STRIPE_PAYMENT_BEHAVIOR_RULES: Optional JSON map of per-market payment behavior overrides, keyed by cart country ("DE") or commercetools store key ("store-mx"). Contains exceptions only — the flat variables above are always the default, and there is no wildcard key. Ported from ct-connect-stripe-checkout so one map can serve both connectors.
flowType, captureMethod (automatic | automatic_async | manual), setupFutureUsage (off_session | on_session | "" | none | null | undefined) and euBankTransferCountry (DE | FR | IE | NL).{"DE":{"captureMethod":"automatic","euBankTransferCountry":"DE"},"MX":{"captureMethod":"manual"}}STRIPE_PAYMENT_FLOW. This map resolves only the two conflicts the Dashboard cannot see: captureMethod, because manual capture and an off_session/on_session mandate each remove customer_balance from the methods Stripe resolves; and euBankTransferCountry, which only chooses which of your IBANs a EUR shopper is told to wire to. Omit the latter and Stripe shows an Irish IBAN, valid for every eurozone shopper since SEPA is a single payment area.STRIPE_ENABLE_MULTI_OPERATIONS: Opt-in Feature - Enables multicapture and multirefund support.
true: Enables multiple partial captures and multiple refunds on payments. Sets request_multicapture: 'if_available' on payment intents. Processes charge.updated and charge.refunded webhook events.false (default): Standard single-capture payment processing. Webhook events are gracefully skipped with informative logging.STRIPE_CAPTURE_METHOD=manualSTRIPE_API_VERSION: Stripe API version to use. Default value is 2025-12-15.clover. Allows merchants to pin to specific Stripe API versions for stability.CT_CUSTOM_TYPE_LAUNCHPAD_PURCHASE_ORDER_KEY: Custom type key for launchpad purchase order number. Default: payment-launchpad-purchase-order.CT_CUSTOM_TYPE_STRIPE_CUSTOMER_KEY: Custom type key for Stripe customer ID. Default: payment-connector-stripe-customer-id.CT_CUSTOM_TYPE_SUBSCRIPTION_LINE_ITEM_KEY: Custom type key for subscription line item. Default: payment-connector-subscription-line-item-type.CT_PRODUCT_TYPE_SUBSCRIPTION_KEY: Product type key for subscription information. Default: payment-connector-subscription-information.Certain configurations are necessary to get started developing this connector, most of which involve updating environment variables in both services (enabler, processor).
Creating a Webhook Endpoint in Stripe (using a dummy URL) is necessary. Once created, retrieve the ID and Signing Secret from the Stripe Console. The Webhook Endpoint configuration is update during the post-deploy script after the connector is deploy. It’s important to set the correct values in the variables so the events are sent to the connector and can be accepted.
Navigate to each service directory and duplicate the .env.template file, renaming the copy to .env. Populate the newly created .env file with the appropriate values.
cp .env.template .env
With the help of docker compose, you can spin up all necessary components required for developing the connector by running the following command from the root directory;
docker compose up
This command would start three services that are required for development.