Adyen / adyen-magento2-express-checkout

Adyen Magento 2 Express Checkout Module
MIT License
8 stars 2 forks source link

[ECP-9155] Apple Pay on product page creates a new quote every time the page is loaded #90

Open pignion opened 2 months ago

pignion commented 2 months ago

Describe the bug When enabling the Apple Pay express checkout on the product page, a new quote is created in Magento's quote table and its associated tables such as quote_item every time a product page is visited, including when it's refreshed. This happens for devices/browsers that both do and don't support Apple Pay.

To Reproduce Steps to reproduce the behavior:

  1. In the Magento Admin, configure and enable Apple Pay express checkout on the product page
  2. Visit a product page, and note a new record inserted into Magento's quote table
  3. Visit a different product page (or refresh the current product page!)
  4. View Magento's quote table

Expected behavior No new database records for customers who did not even initiate an Apple Pay session, such as:

Screenshots Here's an example of records being created in the quote table when refreshing a product page quickly a few times. image

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context

This is what looks like the sequence of operations that leads to the creation of quotes each time a product is viewed

  1. https://github.com/Adyen/adyen-magento2-express-checkout/blob/develop/view/frontend/web/js/applepay/button.js#L83
  2. https://github.com/Adyen/adyen-magento2-express-checkout/blob/develop/view/frontend/web/js/actions/getExpressMethods.js#L57
  3. https://github.com/Adyen/adyen-magento2-express-checkout/blob/develop/etc/webapi.xml#L16
  4. https://github.com/Adyen/adyen-magento2-express-checkout/blob/develop/Api/ExpressInitInterface.php
  5. https://github.com/Adyen/adyen-magento2-express-checkout/blob/develop/Model/ExpressInit.php#L176
candemiralp commented 2 months ago

Hello @pignion,

Thank you for raising this issue and providing all the stack which will be very helpful during our investigation. That was a design decision back in the days of the initial kickstart of the project. However, it looks like the time has come to revisit the approach of initiating express payments on product detail pages since it creates an overhead.

I've already created an investigation ticket for this issue. You will be informed when it's done.

Best regards, Can

oliverde8 commented 1 month ago

Hello,

We raised this issue to Adyen support a few months ago as we had the same problem for one of our clients. At the time this was not in Adyen's roadmap we therefore had to come up with our solution. Sadly we aren't allowed to share the code we made, which is anyway is not compatible as we are not using a Luma-based theme.

It's quite simple, we created a new API /V1/adyen/express/methods, we use the same API for guest users & logged users

This service will call the adyen methods API endpoint with the product SKU & the current store code.

A bit of oversimplified code of what is in the code of the API endpoint

$product  = $this->productRepository->get($sku);
$store = $this->storeManager->getStore($storeCode);

$currencyCode = $store->getCurrentCurrencyCode();

$requestParams= [
    "channel"         => "Web",
    "merchantAccount" => $merchantAccount,
    "countryCode"     => $this->countryHelper->getDefaultCountry($store->getId()),
    "shopperLocale"   => $this->adyenHelper->getCurrentLocaleCode($store->getId()),
    "amount"          => [
        "currency" => $currencyCode
    ]
];

$paymentMethodRequest["amount"]["value"] = (int) $product->getFinalPrice() * 100;

$client = $this->adyenHelper->initializeAdyenClient($store->getId());
$service = $this->adyenHelper->createAdyenCheckoutService($client);
$responseData = $service->paymentMethods($requestParams);

On the frontend side we are not using the expressInit API but our own to display the button.

After that when the Apple pay button is being created, we modified the on-click event here. We validate the form and call the getExpressMethods which will create the cart and apply any cart price rule that is needed.

This way unless the user clicks on the applepay button he is not creating a cart/quote in Magento.

Finally we also added a

if (!window.ApplePaySession) {
      return;
  }

To try and display the apple button with a call to the new /V1/adyen/express/methods API only when needed.

Hopefully, this helps someone to make it happen.