Adyen/adyen-magento2

Payment method 'oxxo' does not work

Closed this issue · 2 comments

Describe the bug
It is not possible to pay with oxxo due to it making an invalid API request to /payments. The request it makes either:

  • Doesn't include the paymentMethod variable
  • Includes statedata from a previous payment attempt

To Reproduce
Steps to reproduce the behavior:

  1. Enable oxxo as a payment method

  2. Try to pay with it

  3. It will refuse

  4. See error

  5. Enable oxxo as a payment method

  6. Try to pay with a test credit card (I use the 4111(..)111 visa card) but use DECLINED as the name so it refuses

  7. Switch to oxxo

  8. Try to pay, and make note that it tries to pay using the previous card information

Expected behavior
A clear and concise description of what you expected to happen.

Magento version
2.4.4-p9

Plugin version
9.6.2

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
We have a headless Magento with a PWA on top, using the drop-in components. There are no customizations on the Adyen module. I have not tried it yet in a clean Magento instance, but I expect to run into similar issues.

Module v8 did not have this issue.

Hello @MagicLegend,

Thank you for raising this issue. However, we've successfully completed a test payment with OXXO on a clean installation.

Screenshot 2024-08-22 at 11 49 19

The error you are getting might be related to the frontend PWA implementation. paymentMethod field should be part of the state data and needs to be generated on the component. In addition to that, plugin's backend has no control over the state data. If you observe wrong/missing state data on your requests, please check the payload of /payment-information call on Magento from frontend to backend.

If the issue is persistent on your end, you can reach out to our support team via support@adyen.com.

I am closing this issue since the issue is not reproducible.

Best Regards,
Can

Hi Can,

Yep, I communicated with your colleague via email about the issue already. I'm not sure what's causing it, but I need a workaround for all payment methods to fix this issue in our PWA setup.

In case it helps anyone, I need to define extra arguments to override the default dataproviders in graphql/di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderPool">
        <arguments>
            <argument name="dataProviders" xsi:type="array">
                <item name="adyen_cc" xsi:type="object">YourVendor\AdyenPayments\Model\AdyenCCDataProvider</item>
                <item name="adyen_hpp" xsi:type="object">YourVendor\AdyenPayments\Model\AdyenHPPDataProvider</item>
                <item name="adyen_oxxo" xsi:type="object">YourVendor\AdyenPayments\Model\AdyenPMDataProvider</item> <!-- Note that this provider can be applied to all payment methods that use the same source provider -->
            </argument>
        </arguments>
    </type>
</config>

Which would be this generic provider that'd simply force-store the statedata:

<?php

namespace YourVendor\AdyenPayments\Model;

use Adyen\Payment\Helper\StateData;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderInterface;
use Adyen\Payment\Model\Api\AdyenStateData;

/**
 * Format Adyen HPP input into value expected when setting payment method
 */
class AdyenPMDataProvider implements AdditionalDataProviderInterface
{
    /**
     * @var StateData
     */
    protected StateData $stateData;

    /**
     * @var MaskedQuoteIdToQuoteIdInterface
     */
    protected MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId;

    /**
     * @var AdyenStateData
     */
    protected AdyenStateData $adyenStateData;

    public function __construct(
        StateData $stateData,
        MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
        AdyenStateData $adyenStateData,
    ) {
        $this->stateData = $stateData;
        $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
        $this->adyenStateData = $adyenStateData;
    }

    /**
     * Format Adyen PM input (aka everything else) into value expected when setting payment method
     *
     * Overrides the default Adyen\Payment\Model\Cart\Payment\AdditionalDataProvider\AdyenPm provider.
     * Ensures the StateData gets saved to the database, so it can be used later. This is required in order to prevent the "Required object 'paymentMethod' is not provided." error
     *
     * @param array $args
     * @return array
     * @throws GraphQlInputException
     */
    public function getData(array $args): array
    {
        $code = $args['code'] ?? null;

        if (!isset($args[$code])) {
            throw new GraphQlInputException(
                __("Required parameter $code for $code is missing.")
            );
        }

        // vvv convert maskedQuoteId to quoteId
        $maskedId = $args[$code]['cartId'];
        $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedId);

        $stateData = $args[$code]['stateData'] ?? '';
        $this->adyenStateData->save($stateData, $quoteId);

        return $args[$code];
    }
}