Problem/Motivation
CyberSource is deprecating the Secure Acceptance Hosted Checkout (SAHC) API, with a sunset date in September 2026. The commerce_cybersource module currently ships two gateways: cybersource_sahc (the deprecated offsite redirect flow) and cybersource_flex (Flex Microform v2, an onsite tokenized card-fields integration). Flex is not being deprecated, but merchants currently on SAHC have no in-module path forward once it sunsets.
CyberSource's recommended replacement for SAHC is Unified Checkout (UC), a hosted JavaScript widget that renders an all-in-one payment UI (manual card entry, with optional support for wallets and Click to Pay) and returns a transient token using the same JWT shape Flex already produces. Since the transient-token lifecycle, the PTS authorization/capture/refund/void calls, and the Payer Authentication (3DS) flow are all already implemented for Flex, Unified Checkout support is primarily a matter of:
- A new capture-context request format (
POST /up/v1/capture-contextsvs. the existing FlexgenerateKey()capture-context call) - A new frontend widget integration replacing the per-field Microform iframes
- A new gateway plugin to host the above
This issue tracks adding a cybersource_unified_checkout payment gateway plugin to the module as a sibling to cybersource_flex and cybersource_sahc, giving merchants currently on SAHC (or anyone wanting the newer widget-based UX) a supported migration path.
Steps to reproduce
N/A, this is a feature request, not a bug report. There is currently no way to use CyberSource Unified Checkout with Drupal Commerce via this module; only SAHC and Flex Microform v2 are supported.
Proposed resolution
Add a new cybersource_unified_checkout gateway plugin alongside the existing two gateways, without modifying cybersource_flex or cybersource_sahc beyond a deprecation notice on the SAHC configuration form.
Recommended approach:
- Extract the REST/PTS logic that's currently duplicated/inline in
Flex.php(createPayment(),capturePayment(),refundPayment(),voidPayment(),onNotify(),getAllowedCardNetworks(),ApiClient/MerchantConfigurationsetup) into a shared abstract base class or trait. BothFlexand the newUnifiedCheckoutplugin extend/use it. This avoids duplicating the payment-processing logic between the two onsite gateways. - Add a
generateCaptureContext()method (replacing Flex'sgenerateKey()for this plugin) that calls the Unified Checkout capture-context endpoint with the richer UC request payload (allowedPaymentTypes,captureMandate,orderInformation, etc.), rather than the minimal Flex Microform request. - Add a new plugin form rendering a single widget mount point (
<div>) instead of per-field Microform iframes, plus a hidden transient-token field. - Add a new JS library that initializes the UC SDK (
Accept(jwt).then(accept => accept.unifiedPayments()).then(up => up.show(...))) and on token receipt submits the checkout form, replacing the Microform field-creation/token JS used by Flex. - Reuse the existing
flex_credit_cardpayment method type (thetransient_tokenfield and JWT-decoding logic increatePaymentMethod()apply identically to UC tokens) rather than introducing a new bundle, unless a clear need for separation emerges during review. - Reuse the existing
FlexReviewcheckout pane andPayerAuthenticationControllerfor 3DS, adapting the visibility checks as needed. Confirm during implementation whether UC's widget handles Payer Authentication device-data collection internally (in which case the external Cardinal setup call becomes unnecessary for this gateway) or whether the existing external flow is still required. - Add a deprecation notice to
CyberSourceSahc::buildConfigurationForm()pointing admins toward the new Unified Checkout gateway, since SAHC itself sunsets in September 2026.
Initial scope is manual card entry only (PANENTRY). Digital wallets (Google Pay, Apple Pay, Paze) and Click to Pay require additional merchant-side EBC portal configuration and are out of scope for this issue, though the capture-context request structure should be wallet-ready (i.e. not hard-coded in a way that prevents adding wallet types later).
User interface changes
- A new "CyberSource Unified Checkout" option appears in the payment gateway plugin list at
/admin/commerce/config/payment-gateways. - The new gateway's configuration form exposes fields for allowed payment types, capture-mandate billing options, locale/country, and checkout display mode (embedded vs. sidebar), in addition to the merchant credentials already used by Flex.
- On checkout, selecting this gateway renders the CyberSource-hosted Unified Checkout widget instead of the current discrete card-number/CVV/expiration fields used by Flex.
- The existing SAHC gateway configuration form gains a deprecation notice linking to the new gateway.
API changes
- New plugin:
Drupal\commerce_cybersource\Plugin\Commerce\PaymentGateway\UnifiedCheckout(and corresponding interface). - New plugin form:
Drupal\commerce_cybersource\PluginForm\UnifiedCheckoutForm. - New JS library
commerce_cybersource/unified-checkoutregistered incommerce_cybersource.libraries.yml. - Likely new shared base class/trait for REST/PTS gateway logic, consumed by both
FlexandUnifiedCheckout(implementation detail, not a BC break for either existing plugin's public API). - No changes to existing
cybersource_flexorcybersource_sahcplugin APIs.
Data model changes
- No new payment method type/bundle is anticipated, the existing
flex_credit_cardbundle and itstransient_tokenfield are expected to be reused, since Unified Checkout produces the same transient-token JWT shape Flex already consumes. This will be confirmed during implementation. - New configuration schema entries under
commerce_payment.commerce_payment_gateway.plugin.cybersource_unified_checkout.
Issue fork commerce_cybersource-3605508
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
vmarchukComment #3
adrianandres commentedComment #10
adrianandres commentedComment #12
adrianandres commented