diff --git a/inc/utils.php b/inc/utils.php index 4fb667d9..bdd68c75 100644 --- a/inc/utils.php +++ b/inc/utils.php @@ -186,11 +186,7 @@ function mollieWooCommerceFormatCurrencyValue($value, $currency) if (in_array($currency, $currenciesWithNoDecimals)) { return number_format($value, 0, '.', ''); } - // trying to avoid floating point issues - $value = $value * 1000; - $value = (int) $value / 1000; //drop the last decimal after the third - $value = round($value, 3); - $value = round($value, 2, PHP_ROUND_HALF_DOWN); //round down, as seems woo like it :) + return number_format($value, 2, '.', ''); } diff --git a/mollie-payments-for-woocommerce.php b/mollie-payments-for-woocommerce.php index 808999e0..7e9d56bd 100644 --- a/mollie-payments-for-woocommerce.php +++ b/mollie-payments-for-woocommerce.php @@ -3,7 +3,7 @@ * Plugin Name: Mollie Payments for WooCommerce * Plugin URI: https://www.mollie.com * Description: Accept payments in WooCommerce with the official Mollie plugin - * Version: 7.5.5 + * Version: 7.6.0 * Author: Mollie * Author URI: https://www.mollie.com * Requires at least: 5.0 @@ -12,7 +12,7 @@ * Domain Path: /languages * License: GPLv2 or later * WC requires at least: 3.9 - * WC tested up to: 8.9 + * WC tested up to: 9.0 * Requires PHP: 7.2 * Requires Plugins: woocommerce */ diff --git a/public/images/trustly.svg b/public/images/trustly.svg new file mode 100644 index 00000000..fefc5da1 --- /dev/null +++ b/public/images/trustly.svg @@ -0,0 +1 @@ + diff --git a/src/MerchantCapture/Capture/Action/CapturePayment.php b/src/MerchantCapture/Capture/Action/CapturePayment.php index 41fd5ab7..8d50f699 100644 --- a/src/MerchantCapture/Capture/Action/CapturePayment.php +++ b/src/MerchantCapture/Capture/Action/CapturePayment.php @@ -13,6 +13,11 @@ class CapturePayment extends AbstractPaymentCaptureAction public function __invoke() { try { + $payment = $this->order->get_payment_method(); + if (strpos($payment, 'mollie') === false) { + return; + } + $paymentId = $this->order->get_meta('_mollie_payment_id'); if (!$paymentId) { diff --git a/src/Payment/MollieObject.php b/src/Payment/MollieObject.php index 84f70d42..7eac75ed 100644 --- a/src/Payment/MollieObject.php +++ b/src/Payment/MollieObject.php @@ -543,7 +543,7 @@ protected function setOrderPaidAndProcessed(WC_Order $order) protected function isOrderPaymentStartedByOtherGateway(WC_Order $order) { // Get the current payment method id for the order - $payment_method_id = $order->get_meta('_payment_method', true); + $payment_method_id = $order->get_payment_method(); // If the current payment method id for the order is not Mollie, return true return strpos($payment_method_id, 'mollie') === false; } @@ -1079,7 +1079,7 @@ protected function getFormatedPhoneNumber(string $phone) $phone = transformPhoneToNLFormat($phone); //check that $phone is in E164 format or can be changed by api - if (preg_match('/^\+[1-9]\d{10,13}$|^[1-9]\d{9,13}$/', $phone)) { + if (is_string($phone) && preg_match('/^\+[1-9]\d{10,13}$|^[1-9]\d{9,13}$/', $phone)) { return $phone; } return null; diff --git a/src/Payment/OrderLines.php b/src/Payment/OrderLines.php index de67b7c5..1c76bbf3 100644 --- a/src/Payment/OrderLines.php +++ b/src/Payment/OrderLines.php @@ -64,12 +64,48 @@ public function order_lines($order, $voucherDefaultCategory) $this->process_shipping(); $this->process_fees(); $this->process_gift_cards(); + $this->process_missmatch(); return [ 'lines' => $this->get_order_lines(), ]; } + private function process_missmatch() + { + $orderTotal = (float) $this->order->get_total(); + $orderTotalRounded = round($orderTotal, 2); + $linesTotal = array_sum(array_map(function ($line) { + return $line['totalAmount']['value']; + }, $this->order_lines)); + $orderTotalDiff = $orderTotalRounded - $linesTotal; + if (abs($orderTotalDiff) > 0) { + $missmatch = [ + 'type' => 'surcharge', + 'name' => __('Rounding difference', 'mollie-payments-for-woocommerce'), + 'quantity' => 1, + 'vatRate' => 0, + 'unitPrice' => [ + 'currency' => $this->currency, + 'value' => $this->dataHelper->formatCurrencyValue($orderTotalDiff, $this->currency), + ], + 'totalAmount' => [ + 'currency' => $this->currency, + 'value' => $this->dataHelper->formatCurrencyValue($orderTotalDiff, $this->currency), + ], + 'vatAmount' => [ + 'currency' => $this->currency, + 'value' => $this->dataHelper->formatCurrencyValue(0, $this->currency), + ], + 'metadata' => [ + 'order_item_id' => 'rounding_diff', + ], + ]; + + $this->order_lines[] = $missmatch; + } + } + /** * Get order lines formatted for Mollie Orders API. * diff --git a/src/PaymentMethods/Giropay.php b/src/PaymentMethods/Giropay.php index 31e2ec00..f7e700fe 100644 --- a/src/PaymentMethods/Giropay.php +++ b/src/PaymentMethods/Giropay.php @@ -27,6 +27,24 @@ protected function getConfig(): array public function getFormFields($generalFormFields): array { - return $generalFormFields; + $notice = [ + 'notice' => [ + 'title' => + sprintf( + __( + '%1$s Paydirekt, the owner of Giropay, has decided to deprecate Giropay. On Monday, 24 June 2024, Mollie was informed that Giropay would cease onboarding new merchants and processing new payments after 30 June 2024. No action is needed from your side. Mollie will automatically remove Giropay as a payment option from your Checkout by 30 June. +Subscription renewals and refunds will continue to be processed as usual beyond June 30. More details can be found in the %2$s Giropay Deprecation FAQ. %3$s', + 'mollie-payments-for-woocommerce' + ), + '

', + '', + '

' + ), + 'type' => 'title', + 'class' => 'notice notice-warning', + 'css' => 'padding:20px;', + ], + ]; + return array_merge($notice, $generalFormFields); } } diff --git a/src/PaymentMethods/Trustly.php b/src/PaymentMethods/Trustly.php new file mode 100644 index 00000000..05179fbb --- /dev/null +++ b/src/PaymentMethods/Trustly.php @@ -0,0 +1,32 @@ + 'trustly', + 'defaultTitle' => __('Trustly', 'mollie-payments-for-woocommerce'), + 'settingsDescription' => '', + 'defaultDescription' => '', + 'paymentFields' => false, + 'instructions' => true, + 'supports' => [ + 'products', + 'refunds', + ], + 'filtersOnBuild' => false, + 'confirmationDelayed' => true, + 'SEPA' => false, + ]; + } + + public function getFormFields($generalFormFields): array + { + return $generalFormFields; + } +} diff --git a/src/Shared/SharedDataDictionary.php b/src/Shared/SharedDataDictionary.php index a78fcd26..3519fdde 100644 --- a/src/Shared/SharedDataDictionary.php +++ b/src/Shared/SharedDataDictionary.php @@ -35,6 +35,7 @@ class SharedDataDictionary 'Mollie_WC_Gateway_Twint', 'Mollie_WC_Gateway_Bancomatpay', 'Mollie_WC_Gateway_Alma', + 'Mollie_WC_Gateway_Trustly', ]; public const MOLLIE_OPTIONS_NAMES = [ diff --git a/tests/php/Functional/Payment/PaymentServiceTest.php b/tests/php/Functional/Payment/PaymentServiceTest.php index 52e7e8bc..acf34319 100644 --- a/tests/php/Functional/Payment/PaymentServiceTest.php +++ b/tests/php/Functional/Payment/PaymentServiceTest.php @@ -98,9 +98,7 @@ public function processPayment_Order_success(){ 'wc_clean' => null, ] ); - $gateway->expects($this->once()) - ->method('getSelectedIssuer') - ->willReturn('ideal_INGBNL2A'); + $expectedRequestToMollie = $this->expectedRequestData($wcOrder); $orderEndpoints->method('create')->with($expectedRequestToMollie); @@ -212,7 +210,7 @@ private function wcOrder($id, $orderKey) [ 'get_id' => $id, 'get_order_key' => $orderKey, - 'get_total' => '20', + 'get_total' => 40.00, 'get_items' => [$this->wcOrderItem()], 'get_billing_first_name' => 'billingggivenName', 'get_billing_last_name' => 'billingfamilyName', @@ -307,7 +305,7 @@ private function expectedRequestData($order){ return [ 'amount' => [ 'currency' => 'EUR', - 'value' => '20.00' + 'value' => '40.00' ], 'redirectUrl' => 'https://webshop.example.org/wc-api/mollie_return?order_id=1&key=wc_order_hxZniP1zDcnM8', @@ -317,7 +315,7 @@ private function expectedRequestData($order){ 'ideal', 'payment' => [ - 'issuer' => 'ideal_INGBNL2A' + 'issuer' => null ], 'locale' => 'en_US', 'billingAddress' => $this->billingAddress($order),