0

We had an issue where some orders that paid using ApplePay would come in with broken invoices. (This issue was 100% of the time for some clients, and sporadic for others). It seems to be around using ApplePay in "Direct" mode. (Store > Configuration > Mollie | Payment methods > ApplePay > Integration Type)

However it was common across all order thats amount_paid would always be null on the order. To determine if you are having the same issue you can check the last 7 days orders with

select so.entity_id, so.increment_id, sop.method, so.grand_total, sop.amount_paid, sop.last_trans_id from sales_order as so
  left join sales_order_payment as sop on so.entity_id = sop.parent_id
  where so.created_at > date_sub(curdate(), interval 7 day) 
    and sop.method = 'mollie_methods_applepay'
    and sop.amount_paid is null
  order by so.entity_id desc;

If there are any records you have the same issue. Whilst the order is in this state:

  • unable to credit the order as Magento believes there is an outstanding amount
  • Current invoice's totals don't match order
  • Still able to invoice the order (even though the customer will have been charged the correct amount)

1 Answer 1

0

The Fix

  1. Ensure you have cweagans/composer-patches installed
  2. Add the following to composer.json
"extra": {
      "patches": {
          "mollie/magento2": {
              "apple pay order invoice issue": "https://raw.githubusercontent.com/zero1limited/magento2-patches/master/patches/Mollie_applepay_invoice_broken.patch"
          }
      }
  }
  1. composer install / composer install --no-dev

You should then be able to test ApplePay.
(N.B at the time of writing it isn't possible to place a test ApplePay order through Mollie, so it needs to be a valid card, but it can be placed on a test system in live mode)

The explanation
Mollie was/is altering the order in two different processes at the same time, and then not synchronizing the data correctly.

From this log

START: /mollie/checkout/redirect/paymentToken/XXXXX
START: /mollie/checkout/webhook/?isAjax=1&orderId=XXXXX
Mollie\Payment\Model\Mollie::processTransactionForOrder [{},"webhook"] [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Mollie\Payment\Model\Client\Payments::processTransaction  [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:336 payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Magento\Sales\Model\OrderRepository::save payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:343 payment status: "paid" [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:344 payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:352 amount: 12.94, currency: USD, order amount: {"currency":"USD","value":"12.94"} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:359 payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:361 payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:364 settlement amount: {"value":"9.86","currency":"GBP"} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Magento\Sales\Model\Order\Payment::pay [{}] [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Magento\Sales\Model\Order\Payment::setAmountPaid [12.94] [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:380 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:382 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Magento\Sales\Model\OrderRepository::save payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:405 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Client/Payments.php:418 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Mollie.php:370 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Mollie.php:374 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
Magento\Sales\Model\OrderRepository::save payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Mollie.php:380 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
/home/magento/htdocs/vendor/mollie/magento2/Model/Mollie.php:382 payment: {"amount_authorized":null,"amount_paid":12.94} [/mollie/checkout/webhook/?isAjax=1&orderId=XXXXX]
END: /mollie/checkout/webhook/?isAjax=1&orderId=XXXXX
Magento\Sales\Model\OrderRepository::save payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/redirect/paymentToken/XXXXX]
Magento\Sales\Model\OrderRepository::save payment: {"amount_authorized":null,"amount_paid":null} [/mollie/checkout/redirect/paymentToken/XXXXX]
END: /mollie/checkout/redirect/paymentToken/XXXXX

(request url in the []) We can see that the "/mollie/checkout/redirect/" starts. (loads the order) Then "mollie/checkout/webhook" starts, updates the order and finishes. Then "/mollie/checkout/redirect" saves it's copy of the order removing the data set by the webhook request.

To get around this I've forced a reload of the order, after the "create payment" method is sent to Mollie. (I've not dug too deep, but it looks like that ->createPayment() actually triggers the webhook request, and will wait for the webhook request to complete before proceeding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.