mollie / Shopware6

MIT License
51 stars 54 forks source link

Creditcard purchase without 3d secure throws exception #20

Closed mbegerau closed 4 years ago

mbegerau commented 4 years ago

Environment

OS: Ubuntu 18.04 Apache: 2.4.29 PHP: 7.3.17 MySQL: 5.7.30 Shopware: 6.1.5 (fresh installation from production repository) Mollie: 1.0.10 Other Plugins: Shopware 6 Demo data (1.0.5)

Problem

Creditcard purchase without 3d secure end with the error "Cannot redirect to an empty URL."

Image: No redirect url error no_redirect_error

Detected cause

https://docs.mollie.com/reference/v2/orders-api/create-order

The Mollie API documentation states:

Once you have created an Order, you should redirect your customer to the URL in the _links.checkout property from the response.

custom/plugins/MolliePayments/src/Handler/PaymentHandler.php, lines 508-510

508        try {
509            $mollieOrder = $this->apiClient->orders->create($orderData);
510        } catch (ApiException $e) {

The $mollieOrder which is created in line 509 usually has three items in the _links array. We made the experience that for creditcards without 3d secure the _links array is missing the "checkout" link.

_Image: No "checkout" link in _links_ no_checkout_link

This can be reproduced with the testing creditcard numbers from: https://docs.mollie.com/guides/mollie-components/testing

Solution suggestion

We decorated the payment handler and fixed this problem by replacing the ending return of the prepare function: original: return isset($mollieOrder) ? $mollieOrder->getCheckoutUrl() : null;

replacement suggestion:

        /**
         * @var string $paymentUrl
         */
        if (isset($mollieOrder)) {
            if ($checkout = $mollieOrder->getCheckoutUrl()) {
                return $checkout;
            } elseif ($mollieOrder->status === 'paid' && $redirect = $mollieOrder->redirectUrl) {
                return $redirect;
            }
        }

        return null;

This leads the customer right back to the finalize payment controller because no external checkout process is required.

Comment

We know that most banks nowadays enforce 3d secure but there are still creditcards out there without it. Also maybe the checkout link could be missing for other reasons, too.

iamreinder commented 4 years ago

We are working on this issue right now. Since version 6.2 of Shopware there are some more options to handle different payment states. And we are working on a broader solution regarding failed payments. This will be solved with that as well.

Be aware that your current solution only checks for the 'paid' status of the Mollie order. This status isn't always set, as Mollie sets this status on the underlying payment object. And further more, the status could be 'authorized' in the case of Klarna Pay Later.

mbegerau commented 4 years ago

Hey, thanks for the info. Unfortunately it's not working for us.

Environment changes compared to original post (completely new and clean shop): Shopware: 6.2.0 Mollie: 1.0.13

Nothing changed compared to the original post: I make a purchase with a non 3d secure credit card.

image: Non 3d secure credit card from https://docs.mollie.com/guides/mollie-components/testing non-3d-secure-creditcard

The order gets successfully created by the API. But the API result returned from rest_create in EndpointAbstract.php (line: 79) does not contain a "checkout" link.

image: Missing checkout url in API result missing-checkout-url

This leads to a null return from prepare in PaymentHandler.php (line: 650). Eventually this results in the exception on line 231 in the pay function in the same file.

image: Exception after paying with non 3d secure credit card empty-redirect-url

The workaround from the original post is still working so we still use it. We don't use Klarna for now, so at the moment we just use the workaround to hotfix the problem with credit cards.