Skip to content

[PaymentServicesPaypal] Empty "Express Checkout" section rendered on checkout payment step when all Payment Services methods are disabled (2.16.0) #41103

Description

@wiktorkoscielny

Preconditions and environment

  • Magento 2.4.x (Open Source or Adobe Commerce) with magento/module-payment-services-paypal 2.16.0 (bundled with the magento/payment-services metapackage; the regression was introduced between 2.14.0 and 2.16.0)
  • Payment Services (PayPal) not used on the store: merchant not onboarded, or all Payment Services payment methods disabled / not displayed at checkout (display_checkout and display_start_of_checkout off for Smart Buttons, Google Pay, Apple Pay)
  • Any other payment provider active (e.g. Mollie, Braintree, offline methods)

Steps to reproduce

  1. Install or upgrade to magento/module-payment-services-paypal 2.16.0 with Payment Services not configured/enabled as described above.
  2. As a guest or customer, add any product to the cart.
  3. Proceed to checkout and open the payment step.

Expected result

No Payment Services / PayPal UI is rendered, since all Payment Services methods are disabled (isVisible: false for every payment_services_paypal_* entry in window.checkoutConfig.payment).

Actual result

An empty "Express Checkout" section is rendered at the top of the payment step: the "Express Checkout" title and the subtitle "Or proceed with the standard checkout", with no payment buttons in between (template Magento_PaymentServicesPaypal/payment/group, rendered via view/frontend/web/template/payment/group.html).

window.checkoutConfig.payment at the same time contains:

payment_services_paypal_smart_buttons: { isVisible: false }
payment_services_paypal_google_pay:    { isVisible: false, express: { isVisible: false } }
payment_services_paypal_apple_pay:     { isVisible: false, express: { isVisible: false } }

Additional information

Root cause

view/frontend/web/js/view/payment/group.js decides whether to render the group by checking mere presence of the express key:

expressMethodEnabled: function () {
    const methods = [
        'payment_services_paypal_smart_buttons',
        'payment_services_paypal_google_pay',
        'payment_services_paypal_apple_pay'
    ];

    return methods.some((method) => {
        return !!_.get(window.checkoutConfig.payment[method], 'express', false);
    });
}

Up to and including 2.14.0 this worked by accident, because GooglePayConfigProvider / ApplePayConfigProvider / SmartButtonsConfigProvider only emitted the express array on their enabled path.

In 2.16.0, Model/GooglePayConfigProvider.php and Model/ApplePayConfigProvider.php were refactored to emit the express config unconditionally:

public function getConfig()
{
    $config = $this->configProvider->getConfig();
    $apsEnabled = $this->baseConfig->isConfigured();
    $config['payment'][self::CODE] = $this->getPaymentConfig($apsEnabled);
    $config['payment'][self::CODE]['express'] = $this->getExpressPaymentConfig($apsEnabled);
    return $config;
}

When the method is disabled, getExpressPaymentConfig() returns ['isVisible' => false]. In JavaScript !!{isVisible: false} is true, so expressMethodEnabled() reports an enabled express method and the empty group is rendered on every store that merely has the module installed.

Suggested fix

Check the actual visibility flag instead of key presence:

return methods.some((method) => {
    return _.get(window.checkoutConfig.payment[method], ['express', 'isVisible'], false) === true;
});

Workaround

A JS mixin on Magento_PaymentServicesPaypal/js/view/payment/group overriding expressMethodEnabled() with the visibility-aware check above, or disabling the Magento_PaymentServicesPaypal module entirely.

Release note

Fixed an empty "Express Checkout" section being displayed on the checkout payment step when Payment Services payment methods are disabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue: needs updateAdditional information is require, waiting for responseReported on 2.4.xIndicates original Magento version for the Issue report.

    Type

    No type

    Projects

    Status
    Needs Update

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions