diff --git a/admin/controller/payment/mollie/base.php b/admin/controller/payment/mollie/base.php index 3ce3eb70..5d7a20c7 100644 --- a/admin/controller/payment/mollie/base.php +++ b/admin/controller/payment/mollie/base.php @@ -155,26 +155,42 @@ public function cleanUp() $catalogControllerDir = DIR_CATALOG . 'controller/'; $catalogModelDir = DIR_CATALOG . 'model/'; - if(file_exists($adminControllerDir . 'extension/payment/mistercash.php')) { - unlink($adminControllerDir . 'extension/payment/mistercash.php'); - $languageFiles = glob($adminLanguageDir .'*/extension/payment/mistercash.php'); - foreach($languageFiles as $file) { + if(file_exists($adminControllerDir . 'extension/payment/mollie_mistercash.php')) { + unlink($adminControllerDir . 'extension/payment/mollie_mistercash.php'); + } + + $languageFiles = glob($adminLanguageDir .'*/extension/payment/mollie_mistercash.php'); + foreach($languageFiles as $file) { + if(file_exists($file)) { unlink($file); } + } + + if(file_exists($catalogControllerDir .'extension/payment/mollie_mistercash.php')) { + unlink($catalogControllerDir .'extension/payment/mollie_mistercash.php'); + } - unlink($catalogControllerDir .'extension/payment/mistercash.php'); - unlink($catalogModelDir .'extension/payment/mistercash.php'); + if(file_exists($catalogModelDir .'extension/payment/mollie_mistercash.php')) { + unlink($catalogModelDir .'extension/payment/mollie_mistercash.php'); } - if(file_exists($adminControllerDir . 'payment/mistercash.php')) { - unlink($adminControllerDir . 'payment/mistercash.php'); - $languageFiles = glob($adminLanguageDir .'*/payment/mistercash.php'); - foreach($languageFiles as $file) { + if(file_exists($adminControllerDir . 'payment/mollie_mistercash.php')) { + unlink($adminControllerDir . 'payment/mollie_mistercash.php'); + } + + $languageFiles = glob($adminLanguageDir .'*/payment/mollie_mistercash.php'); + foreach($languageFiles as $file) { + if(file_exists($file)) { unlink($file); } + } + + if(file_exists($catalogControllerDir .'payment/mollie_mistercash.php')) { + unlink($catalogControllerDir .'payment/mollie_mistercash.php'); + } - unlink($catalogControllerDir .'payment/mistercash.php'); - unlink($catalogModelDir .'payment/mistercash.php'); + if(file_exists($catalogModelDir .'payment/mollie_mistercash.php')) { + unlink($catalogModelDir .'payment/mollie_mistercash.php'); } if (MollieHelper::isOpenCart3x()) { @@ -274,9 +290,9 @@ public function clearData() { public function index () { // Double-check if clean-up has been done - For upgrades - if (empty($this->config->get('payment_mollie_version')) || $this->config->get('payment_mollie_version') < MOLLIE_VERSION) { + if (empty($this->config->get('mollie_payment_version')) || $this->config->get('mollie_payment_version') < MOLLIE_VERSION) { $this->cleanUp(); - Util::config(0)->set('payment_mollie', 'payment_mollie_version', MOLLIE_VERSION); + Util::config(0)->set('mollie_payment', 'mollie_payment_version', MOLLIE_VERSION); } $adminThemeDir = DIR_APPLICATION . 'view/template/'; @@ -291,7 +307,7 @@ public function index () } $adminControllerDir = DIR_APPLICATION . 'controller/'; - if(file_exists($adminControllerDir . 'extension/payment/mistercash.php') || file_exists($adminControllerDir . 'payment/mistercash.php')) { + if(file_exists($adminControllerDir . 'extension/payment/mollie_mistercash.php') || file_exists($adminControllerDir . 'payment/mollie_mistercash.php')) { $this->cleanUp(); } diff --git a/admin/language/de-de/payment/mollie.php b/admin/language/de-de/payment/mollie.php index e11186f4..f278a656 100644 --- a/admin/language/de-de/payment/mollie.php +++ b/admin/language/de-de/payment/mollie.php @@ -134,3 +134,6 @@ $_['text_create_shipment_on_status'] = "Legen Sie eine Sendung an, wenn Sie den Auftrag auf diesen Status setzen"; $_['text_create_shipment_on_order_complete'] = "Erstellen Sie eine Sendung, nachdem Sie den Status zum Bestellen der Bestellung festgelegt haben"; $_['entry_create_shipment_on_order_complete'] = "Erstellen Sie den Versand nach Abschluss der Bestellung"; + +//Button +$_['button_update'] = "Aktualisieren"; diff --git a/admin/language/dutch/payment/mollie.php b/admin/language/dutch/payment/mollie.php index 7eba1abc..f0e24344 100644 --- a/admin/language/dutch/payment/mollie.php +++ b/admin/language/dutch/payment/mollie.php @@ -134,3 +134,6 @@ $_['text_create_shipment_on_status'] = "Maak verzending bij het plaatsen van de bestelling naar deze status"; $_['text_create_shipment_on_order_complete'] = "Maak verzending bij het plaatsen van bestelling om de volledige status te bestellen"; $_['entry_create_shipment_on_order_complete'] = "Maak verzending bij bestelling compleet"; + +//Button +$_['button_update'] = "Bijwerken"; diff --git a/admin/language/en-gb/payment/mollie.php b/admin/language/en-gb/payment/mollie.php index 25e23650..770dee08 100644 --- a/admin/language/en-gb/payment/mollie.php +++ b/admin/language/en-gb/payment/mollie.php @@ -134,3 +134,6 @@ $_['text_create_shipment_on_status'] = "Create shipment upon setting order to this status"; $_['text_create_shipment_on_order_complete'] = "Create shipment upon setting order to order complete status"; $_['entry_create_shipment_on_order_complete'] = "Create shipment upon order complete"; + +//Button +$_['button_update'] = "Update"; diff --git a/admin/language/english/payment/mollie.php b/admin/language/english/payment/mollie.php index 25e23650..770dee08 100644 --- a/admin/language/english/payment/mollie.php +++ b/admin/language/english/payment/mollie.php @@ -134,3 +134,6 @@ $_['text_create_shipment_on_status'] = "Create shipment upon setting order to this status"; $_['text_create_shipment_on_order_complete'] = "Create shipment upon setting order to order complete status"; $_['entry_create_shipment_on_order_complete'] = "Create shipment upon order complete"; + +//Button +$_['button_update'] = "Update"; diff --git a/admin/language/es-es/payment/mollie.php b/admin/language/es-es/payment/mollie.php index 7003956d..9e4e24f5 100644 --- a/admin/language/es-es/payment/mollie.php +++ b/admin/language/es-es/payment/mollie.php @@ -136,3 +136,6 @@ $_['text_create_shipment_on_status'] = "Crear envío al establecer orden a este estado"; $_['text_create_shipment_on_order_complete'] = "Crear envío al establecer orden para ordenar estado completo"; $_['entry_create_shipment_on_order_complete'] = "Crear envío al completar el pedido"; + +//Button +$_['button_update'] = "Actualizar"; diff --git a/admin/language/fr-fr/payment/mollie.php b/admin/language/fr-fr/payment/mollie.php index 3c710443..dc6800c7 100644 --- a/admin/language/fr-fr/payment/mollie.php +++ b/admin/language/fr-fr/payment/mollie.php @@ -133,3 +133,6 @@ $_['text_create_shipment_on_status'] = "Créer un envoi lors du réglage de la commande à ce statut"; $_['text_create_shipment_on_order_complete'] = "Créer une expédition lors du paramétrage de la commande pour passer à la commande"; $_['entry_create_shipment_on_order_complete'] = "Créer une expédition à la fin de la commande"; + +//Button +$_['button_update'] = "Mettre à jour"; diff --git a/admin/language/french/payment/mollie.php b/admin/language/french/payment/mollie.php index 3c710443..dc6800c7 100644 --- a/admin/language/french/payment/mollie.php +++ b/admin/language/french/payment/mollie.php @@ -133,3 +133,6 @@ $_['text_create_shipment_on_status'] = "Créer un envoi lors du réglage de la commande à ce statut"; $_['text_create_shipment_on_order_complete'] = "Créer une expédition lors du paramétrage de la commande pour passer à la commande"; $_['entry_create_shipment_on_order_complete'] = "Créer une expédition à la fin de la commande"; + +//Button +$_['button_update'] = "Mettre à jour"; diff --git a/admin/language/german/payment/mollie.php b/admin/language/german/payment/mollie.php index 746ce3de..5f158c1a 100644 --- a/admin/language/german/payment/mollie.php +++ b/admin/language/german/payment/mollie.php @@ -135,3 +135,6 @@ $_['text_create_shipment_on_status'] = "Legen Sie eine Sendung an, wenn Sie den Auftrag auf diesen Status setzen"; $_['text_create_shipment_on_order_complete'] = "Erstellen Sie eine Sendung, nachdem Sie den Status zum Bestellen der Bestellung festgelegt haben"; $_['entry_create_shipment_on_order_complete'] = "Erstellen Sie den Versand nach Abschluss der Bestellung"; + +//Button +$_['button_update'] = "Aktualisieren"; diff --git a/admin/language/nl-nl/payment/mollie.php b/admin/language/nl-nl/payment/mollie.php index 92f7c6bc..2477b7a6 100644 --- a/admin/language/nl-nl/payment/mollie.php +++ b/admin/language/nl-nl/payment/mollie.php @@ -134,3 +134,6 @@ $_['text_create_shipment_on_status'] = "Maak verzending bij het plaatsen van de bestelling naar deze status"; $_['text_create_shipment_on_order_complete'] = "Maak verzending bij het plaatsen van bestelling om de volledige status te bestellen"; $_['entry_create_shipment_on_order_complete'] = "Maak verzending bij bestelling compleet"; + +//Button +$_['button_update'] = "Bijwerken"; diff --git a/admin/language/spanish/payment/mollie.php b/admin/language/spanish/payment/mollie.php index 264ac47b..f406c298 100644 --- a/admin/language/spanish/payment/mollie.php +++ b/admin/language/spanish/payment/mollie.php @@ -135,3 +135,6 @@ $_['text_create_shipment_on_status'] = "Crear envío al establecer orden a este estado"; $_['text_create_shipment_on_order_complete'] = "Crear envío al establecer orden para ordenar estado completo"; $_['entry_create_shipment_on_order_complete'] = "Crear envío al completar el pedido"; + +//Button +$_['button_update'] = "Actualizar"; diff --git a/catalog/controller/payment/mollie/base.php b/catalog/controller/payment/mollie/base.php index f9fec87b..98c032bf 100644 --- a/catalog/controller/payment/mollie/base.php +++ b/catalog/controller/payment/mollie/base.php @@ -239,7 +239,10 @@ public function payment() "method" => static::MODULE_NAME, ); - $data['payment'] = ["issuer" => $this->formatText($issuer)]; + $data['payment'] = array( + "issuer" => $this->formatText($issuer), + "webhookUrl" => $this->getWebhookUrl() + ); //Order line data $orderProducts = $this->getOrderProducts($order['order_id']); @@ -419,27 +422,13 @@ public function payment() $lines = array_merge($lines, $otherTotals); } - //Check for rounding off issue + //Check for rounding off issue in a general way (for all possible totals) $orderTotal = number_format($amount, 2, '.', ''); - $productTotal = 0; - $shippingTotal = 0; - $couponTotal = 0; - - $productTotalArray = array(); - foreach($orderProducts as $orderProduct) { - $total = $orderProduct['total'] + ($orderProduct['tax'] * $orderProduct['quantity']); - $productTotalArray[] = $this->convertCurrency($total); - } - $productTotal = number_format(array_sum($productTotalArray), 2, '.', ''); + $orderLineTotal = 0; - if(isset($costWithTax)) { - $shippingTotal = number_format($this->convertCurrency($costWithTax), 2, '.', ''); - } - if(isset($unitPriceWithTax)) { - $couponTotal = number_format($this->convertCurrency($unitPriceWithTax), 2, '.', ''); + foreach($lines as $line) { + $orderLineTotal += $line['totalAmount']['value']; } - - $orderLineTotal = number_format($productTotal + $shippingTotal + $couponTotal, 2, '.', ''); if(($orderTotal > $orderLineTotal) && (number_format(($orderTotal - $orderLineTotal), 2, '.', '') == 0.01)) { $lineForDiscount[] = array( @@ -567,8 +556,111 @@ public function webhook() return; } + // Check webhook for order/payment + $id = $this->request->post['id']; + $temp = explode('_', $id); + $idPrefix = $temp[0]; + if($idPrefix == 'ord') { + $this->webhookForOrder($id); + } else { + $this->webhookForPayment($id); + } + + } + + private function webhookForPayment($payment_id) { + + $moduleCode = MollieHelper::getModuleCode(); + + $this->writeToMollieLog("Received webhook for payment_id " . $payment_id); + + $molliePayment = $this->getAPIClient()->payments->get($payment_id); + + $mollieOrderId = $molliePayment->orderId; + + $mollieOrder = $this->getAPIClient()->orders->get($mollieOrderId); + + // Load essentials + Util::load()->model("checkout/order"); + $model = $this->getModuleModel(); + Util::load()->language("payment/mollie"); + + //Get order_id of this transaction from db + $order = $this->model_checkout_order->getOrder($mollieOrder->metadata->order_id); + + //Set transaction ID + $data = array(); + + if($molliePayment) { + $data = array( + 'payment_id' => $payment_id, + 'status' => $molliePayment->status + ); + } + + if(!empty($data)) { + $model->updatePayment($mollieOrder->metadata->order_id, $mollieOrderId, $data); + } + + if (empty($order)) { + header("HTTP/1.0 404 Not Found"); + echo "Could not find order."; + return; + } + + if($order['order_status_id'] != 0) { + return; + } + + // Only process the status if the order is stateless or in 'pending' status. + if (!empty($order['order_status_id']) && $order['order_status_id'] != $this->config->get($moduleCode . "_ideal_pending_status_id")) { + $this->writeToMollieLog("The order was already processed before (order status ID: " . intval($order['order_status_id']) . ")"); + return; + } + + // Payment cancelled. + if ($molliePayment->status == PaymentStatus::STATUS_CANCELED) { + $new_status_id = intval($this->config->get($moduleCode . "_ideal_canceled_status_id")); + + if (!$new_status_id) { + $this->writeToMollieLog("The payment was cancelled. No 'cancelled' status ID is configured, so the order status could not be updated.", true); + return; + } + $this->addOrderHistory($order, $new_status_id, $this->language->get("response_cancelled"), false); + $this->writeToMollieLog("The payment was cancelled and the order was moved to the 'cancelled' status (new status ID: {$new_status_id}).", true); + return; + } + + // Payment expired. + if ($molliePayment->status == PaymentStatus::STATUS_EXPIRED) { + $new_status_id = intval($this->config->get($moduleCode . "_ideal_expired_status_id")); + + if (!$new_status_id) { + $this->writeToMollieLog("The payment expired. No 'expired' status ID is configured, so the order status could not be updated.", true); + return; + } + $this->addOrderHistory($order, $new_status_id, $this->language->get("response_expired"), false); + $this->writeToMollieLog("The payment expired and the order was moved to the 'expired' status (new status ID: {$new_status_id}).", true); + return; + } + + // Otherwise, payment failed. + $new_status_id = intval($this->config->get($moduleCode . "_ideal_failed_status_id")); + + if (!$new_status_id) { + $this->writeToMollieLog("The payment failed. No 'failed' status ID is configured, so the order status could not be updated.", true); + return; + } + $this->addOrderHistory($order, $new_status_id, $this->language->get("response_unknown"), false); + $this->writeToMollieLog("The payment failed for an unknown reason and the order was moved to the 'failed' status (new status ID: {$new_status_id}).", true); + return; + + } + + private function webhookForOrder($order_id) { + $moduleCode = MollieHelper::getModuleCode(); - $order_id = $this->request->post['id']; + $this->writeToMollieLog("Received webhook for order_id " . $order_id); $mollieOrder = $this->getAPIClient()->orders->get($order_id); @@ -624,7 +716,7 @@ public function webhook() } // Order expired. - if ($mollieOrder->status == PaymentStatus::STATUS_CANCELED) { + if ($mollieOrder->status == PaymentStatus::STATUS_EXPIRED) { $new_status_id = intval($this->config->get($moduleCode . "_ideal_expired_status_id")); if (!$new_status_id) { @@ -812,6 +904,14 @@ public function callback() if (($orderDetails->isPaid() || $orderDetails->isAuthorized()) && $order['order_status_id'] != $paid_status_id) { $this->addOrderHistory($order, $paid_status_id, $this->language->get("response_success"), true); $order['order_status_id'] = $paid_status_id; + } else if(!empty($orderDetails->_embedded->payments)) { + + $payment = $orderDetails->_embedded->payments[0]; + if (($payment->status == 'paid') && ($order['order_status_id'] != $paid_status_id)) { + $this->addOrderHistory($order, $paid_status_id, $this->language->get("response_success"), true); + $order['order_status_id'] = $paid_status_id; + } + } /* Check module module setting for shipment creation, diff --git a/catalog/controller/payment/mollie/helper.php b/catalog/controller/payment/mollie/helper.php index 1fdfa7b8..6aad449a 100644 --- a/catalog/controller/payment/mollie/helper.php +++ b/catalog/controller/payment/mollie/helper.php @@ -5,7 +5,7 @@ class MollieHelper { - const PLUGIN_VERSION = "9.0.2"; + const PLUGIN_VERSION = "9.0.3"; // All available modules. These should correspond to the Mollie_API_Object_Method constants. const MODULE_NAME_BANKTRANSFER = "banktransfer"; diff --git a/catalog/model/payment/mollie/base.php b/catalog/model/payment/mollie/base.php index 74f3ccb4..db797822 100644 --- a/catalog/model/payment/mollie/base.php +++ b/catalog/model/payment/mollie/base.php @@ -188,17 +188,19 @@ public function setPayment($order_id, $mollie_order_id) * * @return bool */ - public function updatePayment($transaction_id, $payment_status, $consumer = NULL) + public function updatePayment($order_id, $mollie_order_id, $data, $consumer = NULL) { - if (!empty($transaction_id) && !empty($payment_status)) { + if (!empty($order_id) && !empty($mollie_order_id)) { $this->db->query( sprintf( "UPDATE `%smollie_payments` - SET `bank_status` = '%s' - WHERE `transaction_id` = '%s';", + SET `transaction_id` = '%s', `bank_status` = '%s' + WHERE `order_id` = '%s' AND `mollie_order_id` = '%s';", DB_PREFIX, - $this->db->escape($payment_status), - $this->db->escape($transaction_id) + $this->db->escape($data['payment_id']), + $this->db->escape($data['status']), + $this->db->escape($order_id), + $this->db->escape($mollie_order_id) ) ); diff --git a/system/comercia/load.php b/system/comercia/load.php index e29c3b57..41c0fd97 100644 --- a/system/comercia/load.php +++ b/system/comercia/load.php @@ -22,9 +22,9 @@ function library($library) $bestOption = $this->findBestOption($libDir, $library, "php"); if (!class_exists($className)) { if (class_exists("VQMod")) { - @include_once(\VQMod::modCheck($libDir . $bestOption["name"] . ".php")); + @include_once(\VQMod::modCheck(modification($libDir . $bestOption["name"] . ".php"), $libDir . $bestOption["name"] . ".php")); } else { - @include_once($libDir . $bestOption["name"] . ".php"); + @include_once(modification($libDir . $bestOption["name"] . ".php")); } } @@ -108,9 +108,9 @@ function model($model) $className = $route["class"]; if (!class_exists($className)) { if (class_exists("VQMod")) { - @include_once(\VQMod::modCheck($modelDir . $route["file"] . ".php")); + @include_once(\VQMod::modCheck(modification($modelDir . $route["file"] . ".php"), $modelDir . $route["file"] . ".php")); } else { - @include_once($modelDir . $route["file"] . ".php"); + @include_once(modification($modelDir . $route["file"] . ".php")); } } @@ -234,9 +234,9 @@ function view($view, $data = array()) } $fakeControllerFile = __DIR__ . "/fakeController.php"; if (class_exists("VQMod")) { - require_once(\VQMod::modCheck($fakeControllerFile)); + require_once(\VQMod::modCheck(modification($fakeControllerFile), $fakeControllerFile)); } else { - require_once($fakeControllerFile); + require_once(modification($fakeControllerFile)); } $controller = new FakeController($registry); $result = $controller->getView($view, $data); @@ -326,9 +326,9 @@ function controller($controller) $className = $route["class"]; if (!class_exists($className)) { if (class_exists("VQMod")) { - @include_once(\VQMod::modCheck($controllerDir . $route["file"] . ".php")); + @include_once(\VQMod::modCheck(modification($controllerDir . $route["file"] . ".php"), $controllerDir . $route["file"] . ".php")); } else { - @include_once($controllerDir . $route["file"] . ".php"); + @include_once(modification($controllerDir . $route["file"] . ".php")); } } @@ -393,6 +393,27 @@ private function rewriteLanguage($model) ] ); } + + // Modification Override + function modification($filename) { + if (defined('DIR_CATALOG')) { + $file = DIR_MODIFICATION . 'admin/' . substr($filename, strlen(DIR_APPLICATION)); + } elseif (defined('DIR_OPENCART')) { + $file = DIR_MODIFICATION . 'install/' . substr($filename, strlen(DIR_APPLICATION)); + } else { + $file = DIR_MODIFICATION . 'catalog/' . substr($filename, strlen(DIR_APPLICATION)); + } + + if (substr($filename, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) { + $file = DIR_MODIFICATION . 'system/' . substr($filename, strlen(DIR_SYSTEM)); + } + + if (is_file($file)) { + return $file; + } + + return $filename; + } } ?>