From 177f7a4aa07f4979eecf3b203e8df05f36808da3 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Wed, 13 Nov 2024 11:30:23 +0200 Subject: [PATCH 01/16] Paypal button --- ...IdealFastCheckout.php => FastCheckout.php} | 16 +- upload/Pay/Controller/Payment.php | 230 ++++++++++++++++++ .../extension/payment/paynl_paypal.php | 1 + .../controller/extension/payment/paynl.php | 57 +++-- .../extension/payment/paynl_ideal.php | 223 +---------------- .../extension/payment/paynl_paypal.php | 35 +++ .../view/theme/default/javascript/paynl.js | 88 ++++++- .../view/theme/default/stylesheet/paynl.css | 4 + .../template/extension/paypal_button.twig | 51 ++++ .../default/template/payment/paynl3.twig | 5 +- 10 files changed, 453 insertions(+), 257 deletions(-) rename upload/Pay/Api/{IdealFastCheckout.php => FastCheckout.php} (95%) create mode 100644 upload/catalog/view/theme/default/template/extension/paypal_button.twig diff --git a/upload/Pay/Api/IdealFastCheckout.php b/upload/Pay/Api/FastCheckout.php similarity index 95% rename from upload/Pay/Api/IdealFastCheckout.php rename to upload/Pay/Api/FastCheckout.php index 9b8e8ae..3c3c9ba 100644 --- a/upload/Pay/Api/IdealFastCheckout.php +++ b/upload/Pay/Api/FastCheckout.php @@ -2,7 +2,7 @@ declare(strict_types=1); -class Pay_Api_IdealFastCheckout extends Pay_Api +class Pay_Api_FastCheckout extends Pay_Api { protected $_version = 'v1'; protected $_controller = 'orders'; @@ -150,15 +150,21 @@ public function addProduct($id, $description, $price, $quantity, $vatPercentage, protected function _getPostData() { + if (is_int($this->_paymentMethod)) { + $paymentMethod = [ + 'id' => $this->_paymentMethod, + ]; + } else { + $paymentMethod = $this->_paymentMethod; + } + $postData = [ 'serviceId' => $this->_serviceId, 'amount' => ['value' => $this->_amount], 'description' => $this->_description, 'reference' => $this->_reference, - 'paymentMethod' => [ - 'id' => $this->_paymentMethod, - 'optimize' => $this->_optimize, - ], + 'optimize' => $this->_optimize, + 'paymentMethod' => $paymentMethod, 'returnUrl' => $this->_returnUrl, 'exchangeUrl' => $this->_exchangeUrl, 'order' => ['products' => $this->_products] diff --git a/upload/Pay/Controller/Payment.php b/upload/Pay/Controller/Payment.php index 3d9e7d3..74b7470 100755 --- a/upload/Pay/Controller/Payment.php +++ b/upload/Pay/Controller/Payment.php @@ -397,4 +397,234 @@ public function getErrorMessage($message) return $errorMessage; } + + protected function createBlankFastCheckoutOrder($defaultShippingMethodConfigKey) + { + $this->load->model('setting/extension'); + $this->load->model('checkout/order'); + + $customer_id = $this->customer->isLogged() ? $this->customer->getId() : 0; + $firstname = $this->customer->isLogged() ? $this->customer->getFirstName() : 'Guest'; + $lastname = $this->customer->isLogged() ? $this->customer->getLastName() : 'Customer'; + $email = $this->customer->isLogged() ? $this->customer->getEmail() : 'guest@example.com'; + $telephone = $this->customer->isLogged() ? $this->customer->getTelephone() : ''; + + $order_data = array( + 'invoice_prefix' => $this->config->get('config_invoice_prefix'), + 'store_id' => $this->config->get('config_store_id'), + 'store_name' => $this->config->get('config_name'), + 'store_url' => $this->config->get('config_url'), + 'customer_id' => $customer_id, + 'customer_group_id' => $this->customer->isLogged() ? $this->customer->getGroupId() : 0, + 'firstname' => $firstname, + 'lastname' => $lastname, + 'email' => $email, + 'telephone' => $telephone, + 'payment_firstname' => '', + 'payment_lastname' => '', + 'payment_company' => '', + 'payment_address_1' => '', + 'payment_address_2' => '', + 'payment_city' => '', + 'payment_postcode' => '', + 'payment_country' => '', + 'payment_country_id' => 0, + 'payment_zone' => '', + 'payment_zone_id' => 0, + 'payment_method' => '', + 'payment_code' => '', + 'payment_address_format'=> '', + 'shipping_firstname' => '', + 'shipping_lastname' => '', + 'shipping_company' => '', + 'shipping_address_1' => '', + 'shipping_address_2' => '', + 'shipping_city' => '', + 'shipping_postcode' => '', + 'shipping_country' => '', + 'shipping_country_id' => 0, + 'shipping_zone' => '', + 'shipping_zone_id' => 0, + 'shipping_method' => $this->config->get($defaultShippingMethodConfigKey), + 'shipping_code' => '', + 'shipping_address_format' => '' + ); + + $order_data['products'] = array(); + foreach ($this->cart->getProducts() as $product) { + $order_data['products'][] = array( + 'product_id' => $product['product_id'], + 'name' => $product['name'], + 'model' => $product['model'], + 'quantity' => $product['quantity'], + 'price' => $product['price'], + 'total' => $product['total'], + 'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']), + 'reward' => $product['reward'], + 'option' => isset($product['option']) ? $product['option'] : array() + ); + } + + $order_data['vouchers'] = array(); + if (!empty($this->session->data['vouchers'])) { + foreach ($this->session->data['vouchers'] as $voucher) { + $order_data['vouchers'][] = array( + 'description' => $voucher['description'], + 'code' => $voucher['code'], + 'amount' => $voucher['amount'] + ); + } + } + + $totals = array(); + $total = 0; + $taxes = $this->cart->getTaxes(); + + if (!is_array($taxes)) { + $taxes = array(); + } + + $results = $this->model_setting_extension->getExtensions('total'); + $sort_order = array(); + + foreach ($results as $key => $value) { + $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); + } + + array_multisort($sort_order, SORT_ASC, $results); + + $totalData = array( + 'totals' => &$totals, + 'total' => &$total, + 'taxes' => &$taxes + ); + + $sort_order = array(); + foreach ($results as $key => $value) { + if ($this->config->has('total_' . $value['code'] . '_sort_order')) { + $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); + } else { + $sort_order[$key] = 0; + } + + if ($this->config->get('total_' . $value['code'] . '_status')) { + $this->load->model('extension/total/' . $value['code']); + $this->{'model_extension_total_' . $value['code']}->getTotal($totalData); + } + } + array_multisort($sort_order, SORT_ASC, $results); + + $order_data['totals'] = array(); + foreach ($totals as $total_item) { + $order_data['totals'][] = array( + 'code' => $total_item['code'], + 'title' => $total_item['title'], + 'value' => $total_item['value'], + 'sort_order'=> isset($total_item['sort_order']) ? $total_item['sort_order'] : 0 + ); + } + + $order_data['total'] = $total; + + $order_data['affiliate_id'] = 0; + $order_data['commission'] = 0; + $order_data['marketing_id'] = 0; + $order_data['tracking'] = ''; + + $order_data['comment'] = ''; + $order_data['language_id'] = $this->config->get('config_language_id'); + $order_data['currency_id'] = $this->currency->getId($this->session->data['currency']); + $order_data['currency_code'] = $this->session->data['currency']; + $order_data['currency_value'] = $this->currency->getValue($this->session->data['currency']); + $order_data['ip'] = $this->request->server['REMOTE_ADDR']; + $order_data['forwarded_ip'] = (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) ? $this->request->server['HTTP_X_FORWARDED_FOR'] : ''; + $order_data['user_agent'] = $this->request->server['HTTP_USER_AGENT']; + $order_data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE']; + + $order_id = $this->model_checkout_order->addOrder($order_data); + + $this->model_checkout_order->addOrderHistory($order_id, $this->config->get('config_order_status_id'), '', false); + + $order_data['order_id'] = $order_id; + + return $order_data; + } + + protected function sendRequest($orderData) + { + $this->load->model('extension/payment/' . $this->_paymentMethodName); + $modelName = 'model_extension_payment_' . $this->_paymentMethodName; + + try { + $this->$modelName->log('start fast checkout payment : ' . $this->_paymentMethodName); + $apiFastCheckout = new Pay_Api_FastCheckout(); + $apiFastCheckout->setApiToken($this->config->get('payment_paynl_general_apitoken')); + $apiFastCheckout->setServiceId($this->config->get('payment_paynl_general_serviceid')); + + $apiFastCheckout->setTestmode($this->isTestMode()); + $apiFastCheckout->setOrderNumber($orderData['order_id']); + + $amount = round($orderData['total'] * 100 * $orderData['currency_value']); + $apiFastCheckout->setAmount($amount); + + //Producten toevoegen + foreach ($this->cart->getProducts() as $product) { + $priceWithTax = $this->tax->calculate( + $product['price'] * $orderData['currency_value'], + $product['tax_class_id'], + $this->config->get('config_tax') + ); + + $tax = $priceWithTax - ($product['price'] * $orderData['currency_value']); + + $price = round($priceWithTax * 100); + $apiFastCheckout->addProduct( + $product['product_id'], + $product['name'], + $price, + $product['quantity'], + Pay_Helper::calculateTaxClass($priceWithTax, $tax) + ); + } + + $apiFastCheckout->setDescription(''); + $apiFastCheckout->setReference($orderData['order_id']); + $apiFastCheckout->setOptimize(); + + $paymentMethod = $orderData['payment_method'] ?:$this->_paymentOptionId; + $apiFastCheckout->setPaymentMethod($paymentMethod); + + $returnUrl = $this->url->link('extension/payment/' . $this->_paymentMethodName . '/finishFastCheckout'); + $exchangeUrl = $this->url->link('extension/payment/' . $this->_paymentMethodName . '/exchangeFastCheckout'); + + $customExchangeUrl = $this->config->get('payment_paynl_general_custom_exchange_url'); + $customExchangeUrl = is_null($customExchangeUrl) ? '' : trim($customExchangeUrl); + + if (!empty($customExchangeUrl)) { + $exchangeUrl = htmlspecialchars_decode($customExchangeUrl); + } + + $apiFastCheckout->setReturnUrl($returnUrl); + $apiFastCheckout->setExchangeUrl($exchangeUrl); + + $response['data'] = $apiFastCheckout->doRequest(); + + $this->$modelName->addTransaction( + $response['data']['id'], + $orderData['order_id'], + $this->_paymentOptionId, + $amount, + $apiFastCheckout->getPostData(), + ); + } catch (Pay_Api_Exception $e) { + $message = $this->getErrorMessage($e->getMessage()); + $response['error'] = $this->language->get($message); + } catch (Pay_Exception $e) { + $response['error'] = "Er is een fout opgetreden: " . $e->getMessage(); + } catch (Exception $e) { + $response['error'] = "Onbekende fout: " . $e->getMessage(); + } + + return $response; + } } diff --git a/upload/admin/controller/extension/payment/paynl_paypal.php b/upload/admin/controller/extension/payment/paynl_paypal.php index add674b..fd3931d 100755 --- a/upload/admin/controller/extension/payment/paynl_paypal.php +++ b/upload/admin/controller/extension/payment/paynl_paypal.php @@ -10,4 +10,5 @@ class ControllerExtensionPaymentPaynlPaypal extends Pay_Controller_Admin protected $_paymentMethodName = 'paynl_paypal'; protected $_defaultLabel = 'PayPal'; + protected $_fastCheckout = true; } diff --git a/upload/catalog/controller/extension/payment/paynl.php b/upload/catalog/controller/extension/payment/paynl.php index 48c2d57..34fc405 100644 --- a/upload/catalog/controller/extension/payment/paynl.php +++ b/upload/catalog/controller/extension/payment/paynl.php @@ -105,12 +105,16 @@ public function paynlDoAutoCapture($apiToken, $serviceId, $transactionId, $order } public function addFastCheckoutButtons(&$route, &$data, &$output) { + if (!$this->cart->hasProducts()) { + return; + } + if (!in_array('cart', $this->config->get('payment_paynl_ideal_button_places'))) { return; } - $this->prepareOutput($output); - $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(); + $this->loadResources($output); + $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(['paypal_container_id' => 'paypal-button-container-2']); if (!empty($payMethodsWithFastCheckout)) { $data['fast_checkout_buttons'] = array_filter($payMethodsWithFastCheckout); @@ -130,9 +134,7 @@ public function addFastCheckoutMiniCartButtons(&$route, &$data, &$output) { return; } - $styleTag = ''; - $output = str_replace('
', $styleTag . '
', $output); - + $this->loadResources($output); $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(); if (!empty($payMethodsWithFastCheckout)) { @@ -153,15 +155,14 @@ public function addFastCheckoutProductPageButtons(&$route, &$data, &$output) { return; } - $this->prepareOutput($output); - $scriptTag = ''; - $output = str_replace('', $scriptTag . '', $output); - - $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(); + $this->loadResources($output); + $paypalContainerId = $this->cart->hasProducts() ? ['paypal_container_id' => 'paypal-button-container-2'] : null; + $payMethodsWithFastCheckout = $this->getFastCheckoutButtons($paypalContainerId); if (!empty($payMethodsWithFastCheckout)) { $data['fast_checkout_buttons'] = array_filter($payMethodsWithFastCheckout); $fastCheckoutButtonsHtml = $this->load->view('payment/fast_checkout_product_buttons', $data); + $fastCheckoutButtonsHtml .= '
'; $textLoading = $data['text_loading']; $buttonCart = $data['button_cart']; @@ -171,12 +172,7 @@ public function addFastCheckoutProductPageButtons(&$route, &$data, &$output) { } } - private function prepareOutput(&$output) { - $styleTag = ''; - $output = str_replace('', $styleTag . '', $output); - } - - private function getFastCheckoutButtons() { + private function getFastCheckoutButtons($options = array()) { $this->load->model('setting/extension'); $results = $this->model_setting_extension->getExtensions('payment'); $payMethodsWithFastCheckout = array(); @@ -190,7 +186,9 @@ private function getFastCheckoutButtons() { $allowedToProceed = !($onlyGuests && $customerIsLogged); if ($fastCheckout === true && $allowedToProceed === true) { - $payMethodsWithFastCheckout[] = $this->getFastCheckoutButtonLayout($result['code']); + $paypalContainerId = isset($options['paypal_container_id']) ? $options['paypal_container_id'] : null; + + $payMethodsWithFastCheckout[] = $this->getFastCheckoutButtonLayout($result['code'], $paypalContainerId); } } } @@ -198,16 +196,31 @@ private function getFastCheckoutButtons() { return $payMethodsWithFastCheckout; } - private function getFastCheckoutButtonLayout($methodCode) { + private function getFastCheckoutButtonLayout($methodCode, $paypalContainerId) { + if ($paypalContainerId === null) { + $paypalContainerId = 'paypal-button-container'; + } + + $url = 'index.php?route=extension/payment/' . $methodCode . '/initFastCheckout'; + switch ($methodCode) { case 'paynl_ideal': - $url = 'index.php?route=extension/payment/' . $methodCode . '/initFastCheckout'; - - return ' + return ''; + case 'paynl_paypal': + $total_amount = $this->cart->getTotal(); + + return '
'; default: null; } } + + private function loadResources(&$output) { + $styleTag = ''; + $scriptTag = ''; + + $output = str_replace('
', '
' . $styleTag . $scriptTag, $output); + } } diff --git a/upload/catalog/controller/extension/payment/paynl_ideal.php b/upload/catalog/controller/extension/payment/paynl_ideal.php index 0ed2e90..15aef0c 100644 --- a/upload/catalog/controller/extension/payment/paynl_ideal.php +++ b/upload/catalog/controller/extension/payment/paynl_ideal.php @@ -10,152 +10,7 @@ class ControllerExtensionPaymentPaynlideal extends Pay_Controller_Payment protected $_paymentMethodName = 'paynl_ideal'; public function initFastCheckout() { - $this->load->model('setting/extension'); - $this->load->model('checkout/order'); - - $customer_id = $this->customer->isLogged() ? $this->customer->getId() : 0; - $firstname = $this->customer->isLogged() ? $this->customer->getFirstName() : 'Guest'; - $lastname = $this->customer->isLogged() ? $this->customer->getLastName() : 'Customer'; - $email = $this->customer->isLogged() ? $this->customer->getEmail() : 'guest@example.com'; - $telephone = $this->customer->isLogged() ? $this->customer->getTelephone() : ''; - - $order_data = array( - 'invoice_prefix' => $this->config->get('config_invoice_prefix'), - 'store_id' => $this->config->get('config_store_id'), - 'store_name' => $this->config->get('config_name'), - 'store_url' => $this->config->get('config_url'), - 'customer_id' => $customer_id, - 'customer_group_id' => $this->customer->isLogged() ? $this->customer->getGroupId() : 0, - 'firstname' => $firstname, - 'lastname' => $lastname, - 'email' => $email, - 'telephone' => $telephone, - 'payment_firstname' => '', - 'payment_lastname' => '', - 'payment_company' => '', - 'payment_address_1' => '', - 'payment_address_2' => '', - 'payment_city' => '', - 'payment_postcode' => '', - 'payment_country' => '', - 'payment_country_id' => 0, - 'payment_zone' => '', - 'payment_zone_id' => 0, - 'payment_method' => '', - 'payment_code' => '', - 'payment_address_format'=> '', - 'shipping_firstname' => '', - 'shipping_lastname' => '', - 'shipping_company' => '', - 'shipping_address_1' => '', - 'shipping_address_2' => '', - 'shipping_city' => '', - 'shipping_postcode' => '', - 'shipping_country' => '', - 'shipping_country_id' => 0, - 'shipping_zone' => '', - 'shipping_zone_id' => 0, - 'shipping_method' => $this->config->get('payment_paynl_ideal_default_shipping'), - 'shipping_code' => '', - 'shipping_address_format' => '' - ); - - $order_data['products'] = array(); - foreach ($this->cart->getProducts() as $product) { - $order_data['products'][] = array( - 'product_id' => $product['product_id'], - 'name' => $product['name'], - 'model' => $product['model'], - 'quantity' => $product['quantity'], - 'price' => $product['price'], - 'total' => $product['total'], - 'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']), - 'reward' => $product['reward'], - 'option' => isset($product['option']) ? $product['option'] : array() - ); - } - - $order_data['vouchers'] = array(); - if (!empty($this->session->data['vouchers'])) { - foreach ($this->session->data['vouchers'] as $voucher) { - $order_data['vouchers'][] = array( - 'description' => $voucher['description'], - 'code' => $voucher['code'], - 'amount' => $voucher['amount'] - ); - } - } - - $totals = array(); - $total = 0; - $taxes = $this->cart->getTaxes(); - - if (!is_array($taxes)) { - $taxes = array(); - } - - $results = $this->model_setting_extension->getExtensions('total'); - $sort_order = array(); - - foreach ($results as $key => $value) { - $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); - } - - array_multisort($sort_order, SORT_ASC, $results); - - $totalData = array( - 'totals' => &$totals, - 'total' => &$total, - 'taxes' => &$taxes - ); - - $sort_order = array(); - foreach ($results as $key => $value) { - if ($this->config->has('total_' . $value['code'] . '_sort_order')) { - $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); - } else { - $sort_order[$key] = 0; - } - - if ($this->config->get('total_' . $value['code'] . '_status')) { - $this->load->model('extension/total/' . $value['code']); - $this->{'model_extension_total_' . $value['code']}->getTotal($totalData); - } - } - array_multisort($sort_order, SORT_ASC, $results); - - $order_data['totals'] = array(); - foreach ($totals as $total_item) { - $order_data['totals'][] = array( - 'code' => $total_item['code'], - 'title' => $total_item['title'], - 'value' => $total_item['value'], - 'sort_order'=> isset($total_item['sort_order']) ? $total_item['sort_order'] : 0 - ); - } - - $order_data['total'] = $total; - - $order_data['affiliate_id'] = 0; - $order_data['commission'] = 0; - $order_data['marketing_id'] = 0; - $order_data['tracking'] = ''; - - $order_data['comment'] = ''; - $order_data['language_id'] = $this->config->get('config_language_id'); - $order_data['currency_id'] = $this->currency->getId($this->session->data['currency']); - $order_data['currency_code'] = $this->session->data['currency']; - $order_data['currency_value'] = $this->currency->getValue($this->session->data['currency']); - $order_data['ip'] = $this->request->server['REMOTE_ADDR']; - $order_data['forwarded_ip'] = (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) ? $this->request->server['HTTP_X_FORWARDED_FOR'] : ''; - $order_data['user_agent'] = $this->request->server['HTTP_USER_AGENT']; - $order_data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE']; - - $order_id = $this->model_checkout_order->addOrder($order_data); - - $this->model_checkout_order->addOrderHistory($order_id, $this->config->get('config_order_status_id'), '', false); - - $order_data['order_id'] = $order_id; + $order_data = $this->createBlankFastCheckoutOrder('payment_paynl_ideal_default_shipping'); $response = $this->sendRequest($order_data); @@ -166,82 +21,6 @@ public function initFastCheckout() { header("Location: " . $response['data']['links']['redirect']); } - private function sendRequest($orderData) - { - $this->load->model('extension/payment/' . $this->_paymentMethodName); - $modelName = 'model_extension_payment_' . $this->_paymentMethodName; - - try { - $this->$modelName->log('start fast checkout payment : ' . $this->_paymentMethodName); - $apiFastCheckout = new Pay_Api_IdealFastCheckout(); - $apiFastCheckout->setApiToken($this->config->get('payment_paynl_general_apitoken')); - $apiFastCheckout->setServiceId($this->config->get('payment_paynl_general_serviceid')); - - $apiFastCheckout->setTestmode($this->isTestMode()); - $apiFastCheckout->setOrderNumber($orderData['order_id']); - - $amount = round($orderData['total'] * 100 * $orderData['currency_value']); - $apiFastCheckout->setAmount($amount); - - //Producten toevoegen - foreach ($this->cart->getProducts() as $product) { - $priceWithTax = $this->tax->calculate( - $product['price'] * $orderData['currency_value'], - $product['tax_class_id'], - $this->config->get('config_tax') - ); - - $tax = $priceWithTax - ($product['price'] * $orderData['currency_value']); - - $price = round($priceWithTax * 100); - $apiFastCheckout->addProduct( - $product['product_id'], - $product['name'], - $price, - $product['quantity'], - Pay_Helper::calculateTaxClass($priceWithTax, $tax) - ); - } - - $apiFastCheckout->setDescription('iDEAL Fast Checkout'); - $apiFastCheckout->setReference($orderData['order_id']); - $apiFastCheckout->setOptimize(); - $apiFastCheckout->setPaymentMethod(); - - $returnUrl = $this->url->link('extension/payment/' . $this->_paymentMethodName . '/finishFastCheckout'); - $exchangeUrl = $this->url->link('extension/payment/' . $this->_paymentMethodName . '/exchangeFastCheckout'); - - $customExchangeUrl = $this->config->get('payment_paynl_general_custom_exchange_url'); - $customExchangeUrl = is_null($customExchangeUrl) ? '' : trim($customExchangeUrl); - - if (!empty($customExchangeUrl)) { - $exchangeUrl = htmlspecialchars_decode($customExchangeUrl); - } - - $apiFastCheckout->setReturnUrl($returnUrl); - $apiFastCheckout->setExchangeUrl($exchangeUrl); - - $response['data'] = $apiFastCheckout->doRequest(); - - $this->$modelName->addTransaction( - $response['data']['id'], - $orderData['order_id'], - $this->_paymentOptionId, - $amount, - $apiFastCheckout->getPostData(), - ); - } catch (Pay_Api_Exception $e) { - $message = $this->getErrorMessage($e->getMessage()); - $response['error'] = $this->language->get($message); - } catch (Pay_Exception $e) { - $response['error'] = "Er is een fout opgetreden: " . $e->getMessage(); - } catch (Exception $e) { - $response['error'] = "Onbekende fout: " . $e->getMessage(); - } - - return $response; - } - /** * @return void */ diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index a6d743f..a55c6dd 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -8,4 +8,39 @@ class ControllerExtensionPaymentPaynlpaypal extends Pay_Controller_Payment { protected $_paymentOptionId = 138; protected $_paymentMethodName = 'paynl_paypal'; + + public function initFastCheckout() { + $order_data = $this->createBlankFastCheckoutOrder('payment_paynl_paypal_default_shipping'); + $this->session->data['fast_checkout_paypal_order'] = $order_data; + + $totalAmount = $this->cart->getTotal(); + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode([ + 'order_id' => $order_data['order_id'], + 'total_amount' => number_format($totalAmount, 2, '.', '') + ])); + } + + public function handleResult() + { + $rawData = file_get_contents('php://input'); + $data = json_decode($rawData, true); + + $order_data = $this->session->data['fast_checkout_paypal_order']; + $order_data['payment_method'] = [ + 'id' => $this->_paymentOptionId, + 'input' => [ + 'orderId' => $data['orderID'] + ] + ]; + + //TODO: need to add request to paynl to capture payment and get payer info + $response = $this->sendRequest($order_data); + + $this->response->setOutput(json_encode($response)); + + + + } } diff --git a/upload/catalog/view/theme/default/javascript/paynl.js b/upload/catalog/view/theme/default/javascript/paynl.js index b7ae30f..f0311df 100644 --- a/upload/catalog/view/theme/default/javascript/paynl.js +++ b/upload/catalog/view/theme/default/javascript/paynl.js @@ -1,7 +1,8 @@ jQuery(document).ready(function () { - $('.fast-checkout-block a').on('click', function(event) { + $('.fast-checkout-block a').off('click').on('click', function (event) { event.preventDefault(); - $(this).disabled = true + + $(this).disabled = true; $('#button-cart').click(); var method = $(this).data('method'); @@ -9,17 +10,94 @@ jQuery(document).ready(function () { url: 'index.php?route=extension/payment/' + method + '/initFastCheckout', method: 'POST', contentType: 'application/json', - data: JSON.stringify({ method: method }), - success: function(response) { + data: JSON.stringify({method: method}), + success: function (response) { if (typeof response === "string") { response = JSON.parse(response); } window.location.href = response.data.links.redirect }, - error: function(xhr, status, error) { + error: function (xhr, status, error) { console.error('Error:', error.data); } }); }); + + waitForElement('#paypal-button-container', function () { + renderPayPalButton('#paypal-button-container'); + }); + + waitForElement('#paypal-button-container-2', function () { + renderPayPalButton('#paypal-button-container-2'); + }); }); + +function renderPayPalButton(containerSelector) { + if (!jQuery(containerSelector).is(':empty')) return; // Avoid re-rendering + + const buttonConfig = { + style: { + layout: 'horizontal', + color: 'blue', + shape: 'rect', + label: 'paypal', + height: 34 + }, + createOrder: function (data, actions) { + $('#button-cart').click(); + + return fetch('index.php?route=extension/payment/paynl_paypal/initFastCheckout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(response => response.json()) + .then(orderData => { + return actions.order.create({ + purchase_units: [{ + reference_id: orderData.order_id, + amount: { + value: orderData.total_amount + } + }] + }); + }); + }, + onApprove: function (data, actions) { + return fetch('index.php?route=extension/payment/paynl_paypal/handleResult', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }) + .then(response => response.json()) + .then(result => { + console.log(result); + // window.location.href = 'index.php?route=checkout/success'; + }) + .catch(error => console.error('Payment failed:', error)); + } + }; + + paypal.Buttons(buttonConfig).render(containerSelector); +} + +function waitForElement(selector, callback, interval = 200, maxAttempts = 50) { + let attempts = 0; + + function checkElement() { + if (jQuery(selector).length) { + callback(); + } else { + attempts++; + if (attempts < maxAttempts) { + setTimeout(checkElement, interval); + } + } + } + + checkElement(); +} diff --git a/upload/catalog/view/theme/default/stylesheet/paynl.css b/upload/catalog/view/theme/default/stylesheet/paynl.css index dd11620..dfbb19e 100644 --- a/upload/catalog/view/theme/default/stylesheet/paynl.css +++ b/upload/catalog/view/theme/default/stylesheet/paynl.css @@ -21,3 +21,7 @@ .fast-checkout-btn { margin-right: 4px; } + +.fast-checkout-btn-margin { + margin-bottom: 4px; +} diff --git a/upload/catalog/view/theme/default/template/extension/paypal_button.twig b/upload/catalog/view/theme/default/template/extension/paypal_button.twig new file mode 100644 index 0000000..52ddb31 --- /dev/null +++ b/upload/catalog/view/theme/default/template/extension/paypal_button.twig @@ -0,0 +1,51 @@ +
+ diff --git a/upload/catalog/view/theme/default/template/payment/paynl3.twig b/upload/catalog/view/theme/default/template/payment/paynl3.twig index b5237b4..d570db9 100755 --- a/upload/catalog/view/theme/default/template/payment/paynl3.twig +++ b/upload/catalog/view/theme/default/template/payment/paynl3.twig @@ -17,7 +17,6 @@ - {% if dob %}
@@ -49,7 +48,7 @@
-
+
{% else %} {% endif %} @@ -63,7 +62,7 @@
-
+ {% else %} {% endif %} From 9ebb84c4e103f38f3e96a8034aab2b78011121f7 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Mon, 18 Nov 2024 13:46:38 +0200 Subject: [PATCH 02/16] Paypal button --- upload/Pay/Controller/Admin.php | 10 + upload/Pay/Controller/Payment.php | 65 +++++ upload/Pay/Model.php | 40 +++ .../extension/payment/paynl_paypal.php | 1 + .../de-de/extension/payment/paynl3.php | 1 + .../fr-fr/extension/payment/paynl3.php | 1 + .../nl-nl/extension/payment/paynl3.php | 1 + .../template/extension/payment/paynl3.twig | 16 ++ .../controller/extension/payment/paynl.php | 33 +-- .../extension/payment/paynl_ideal.php | 71 +---- .../extension/payment/paynl_paypal.php | 252 +++++++++++++++++- .../model/extension/payment/paynl_ideal.php | 40 --- .../view/theme/default/javascript/paynl.js | 96 +++++-- 13 files changed, 483 insertions(+), 144 deletions(-) diff --git a/upload/Pay/Controller/Admin.php b/upload/Pay/Controller/Admin.php index 77534b1..1c4889a 100755 --- a/upload/Pay/Controller/Admin.php +++ b/upload/Pay/Controller/Admin.php @@ -99,6 +99,16 @@ public function index() ); } } + + if (property_exists($this, '_clientId') && $this->_clientId === true) { + $clientIdName = 'payment_' . $this->_paymentMethodName . '_client_id'; + $data['fast_checkout_client_id_name'] = $clientIdName; + $data['fast_checkout_client_id'] = isset($settings[$clientIdName]) ? $settings[$clientIdName] : ''; + + $clientToken = 'payment_' . $this->_paymentMethodName . '_client_token'; + $data['fast_checkout_client_token_name'] = $clientToken; + $data['fast_checkout_client_token'] = isset($settings[$clientToken]) ? $settings[$clientToken] : '';; + } } if ($reqMethod == 'POST') { diff --git a/upload/Pay/Controller/Payment.php b/upload/Pay/Controller/Payment.php index 74b7470..50d23bc 100755 --- a/upload/Pay/Controller/Payment.php +++ b/upload/Pay/Controller/Payment.php @@ -627,4 +627,69 @@ protected function sendRequest($orderData) return $response; } + + public function exchangeFastCheckout() { + $rawData = file_get_contents('php://input'); + $webhookData = json_decode($rawData, true); + + if (empty($webhookData)) { + $webhookData = $this->request->post; + } + + $order_id = $webhookData['object']['reference']; + + $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); + + $this->load->model('extension/payment/' . $this->_paymentMethodName); + $modelName = 'model_extension_payment_' . $this->_paymentMethodName; + + $this->load->model('checkout/order'); + + if ($status === Pay_Model::STATUS_COMPLETE) { + $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; + $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; + $customer = $webhookData['object']['checkoutData']['customer']; + + $paymentData = [ + 'firstname' => $customer['firstName'], + 'lastname' => $customer['lastName'], + 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], + 'city' => $billingAddress['city'], + 'postcode' => $billingAddress['zipCode'], + 'country' => $billingAddress['countryCode'], + 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] + ]; + + $shippingData = [ + 'firstname' => $customer['firstName'], + 'lastname' => $customer['lastName'], + 'address_1' => $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'], + 'city' => $shippingAddress['city'], + 'postcode' => $shippingAddress['zipCode'], + 'country' => $shippingAddress['countryCode'] + ]; + + $customerData = [ + 'email' => $customer['email'], + 'phone' => $customer['phone'], + 'lastname' => $customer['lastName'], + 'firstname' => $customer['firstName'], + ]; + + $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); + $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); + + $this->model_checkout_order->addOrderHistory($order_id, 2, 'Order paid via fast checkout.'); + + $this->response->setOutput(json_encode(['status' => 'success'])); + } + + if ($status === Pay_Model::STATUS_CANCELED) { + $this->model_checkout_order->addOrderHistory($order_id, 7, 'Order cancelled'); + + $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); + + $this->response->setOutput(json_encode(['status' => 'cancelled'])); + } + } } diff --git a/upload/Pay/Model.php b/upload/Pay/Model.php index 669a957..3cf95cb 100755 --- a/upload/Pay/Model.php +++ b/upload/Pay/Model.php @@ -490,4 +490,44 @@ public function processTransaction($transactionId) return $status; } + + public function updateOrderAfterWebhook($order_id, $payment_data, $shipping_data, $customer_data) { + $order_query = $this->db->query("SELECT customer_id FROM `" . DB_PREFIX . "order` WHERE order_id = '" . (int)$order_id . "'"); + + if ($order_query->num_rows) { + $query = "UPDATE `" . DB_PREFIX . "order` SET "; + $fields = array(); + + $fields[] = "payment_firstname = '" . $this->db->escape($payment_data['firstname']) . "'"; + $fields[] = "payment_lastname = '" . $this->db->escape($payment_data['lastname']) . "'"; + $fields[] = "payment_address_1 = '" . $this->db->escape($payment_data['address_1']) . "'"; + $fields[] = "payment_city = '" . $this->db->escape($payment_data['city']) . "'"; + $fields[] = "payment_postcode = '" . $this->db->escape($payment_data['postcode']) . "'"; + $fields[] = "payment_country = '" . $this->db->escape($payment_data['country']) . "'"; + $fields[] = "payment_method = '" . $this->db->escape($payment_data['method']) . "'"; + + $fields[] = "shipping_firstname = '" . $this->db->escape($shipping_data['firstname']) . "'"; + $fields[] = "shipping_lastname = '" . $this->db->escape($shipping_data['lastname']) . "'"; + $fields[] = "shipping_address_1 = '" . $this->db->escape($shipping_data['address_1']) . "'"; + $fields[] = "shipping_city = '" . $this->db->escape($shipping_data['city']) . "'"; + $fields[] = "shipping_postcode = '" . $this->db->escape($shipping_data['postcode']) . "'"; + $fields[] = "shipping_country = '" . $this->db->escape($shipping_data['country']) . "'"; + + if ($order_query->row['customer_id'] == 0) { + $fields[] = "firstname = '" . $this->db->escape($customer_data['firstname']) . "'"; + $fields[] = "lastname = '" . $this->db->escape($customer_data['lastname']) . "'"; + $fields[] = "email = '" . $this->db->escape($customer_data['email']) . "'"; + $fields[] = "telephone = '" . $this->db->escape($customer_data['phone']) . "'"; + } + + $query .= implode(", ", $fields); + $query .= " WHERE order_id = '" . (int)$order_id . "'"; + + $this->db->query($query); + + echo "Order information updated successfully."; + } else { + echo "Order not found."; + } + } } diff --git a/upload/admin/controller/extension/payment/paynl_paypal.php b/upload/admin/controller/extension/payment/paynl_paypal.php index fd3931d..bd3c081 100755 --- a/upload/admin/controller/extension/payment/paynl_paypal.php +++ b/upload/admin/controller/extension/payment/paynl_paypal.php @@ -11,4 +11,5 @@ class ControllerExtensionPaymentPaynlPaypal extends Pay_Controller_Admin protected $_defaultLabel = 'PayPal'; protected $_fastCheckout = true; + protected $_clientId = true; } diff --git a/upload/admin/language/de-de/extension/payment/paynl3.php b/upload/admin/language/de-de/extension/payment/paynl3.php index 7f3e45f..da4b516 100644 --- a/upload/admin/language/de-de/extension/payment/paynl3.php +++ b/upload/admin/language/de-de/extension/payment/paynl3.php @@ -78,6 +78,7 @@ $_['text_display_fast_checkout_tooltip'] = 'Aktivieren oder deaktivieren Sie die Schnellkauf-Schaltfläche im Warenkorb.'; $_['text_default_shipping_method'] = 'Standard-Versandmethode'; $_['text_only_guest'] = 'Nur für Gäste'; +$_['client_id'] = 'Kunden-ID'; $_['text_status_pending'] = 'Bestellstatus wartet auf Zahlung'; $_['text_status_pending_tooltip'] = 'Der Status der Bestellung, wenn die Zahlung begonnen, aber noch nicht abgeschlossen ist'; diff --git a/upload/admin/language/fr-fr/extension/payment/paynl3.php b/upload/admin/language/fr-fr/extension/payment/paynl3.php index 55251ca..f223144 100644 --- a/upload/admin/language/fr-fr/extension/payment/paynl3.php +++ b/upload/admin/language/fr-fr/extension/payment/paynl3.php @@ -77,6 +77,7 @@ $_['text_display_fast_checkout_tooltip'] = 'Activer ou désactiver le bouton de paiement rapide dans le panier.'; $_['text_default_shipping_method'] = 'Méthode d\'expédition par défaut'; $_['text_only_guest'] = 'Uniquement pour les invités'; +$_['client_id'] = 'Identifiant client'; $_['text_status_pending'] = 'Statut de la commande en attente de paiement'; $_['text_status_pending_tooltip'] = 'Le statut de la commande lorsque le paiement est commencé, mais pas encore terminé'; diff --git a/upload/admin/language/nl-nl/extension/payment/paynl3.php b/upload/admin/language/nl-nl/extension/payment/paynl3.php index 343c294..d115e8a 100755 --- a/upload/admin/language/nl-nl/extension/payment/paynl3.php +++ b/upload/admin/language/nl-nl/extension/payment/paynl3.php @@ -94,6 +94,7 @@ $_['text_display_fast_checkout_tooltip'] = 'Schakel de Fast Checkout-knop in of uit in de winkelwagen.'; $_['text_default_shipping_method'] = 'Standaard verzendmethode'; $_['text_only_guest'] = 'Alleen voor gasten'; +$_['client_id'] = 'Klant-ID'; $_['text_status_pending'] = 'Order status wacht op betaling'; $_['text_status_pending_tooltip'] = 'De status van de order wanneer de betaling is gestart, maar nog niet afgerond'; diff --git a/upload/admin/view/template/extension/payment/paynl3.twig b/upload/admin/view/template/extension/payment/paynl3.twig index e0bbbc9..0e46eb3 100755 --- a/upload/admin/view/template/extension/payment/paynl3.twig +++ b/upload/admin/view/template/extension/payment/paynl3.twig @@ -156,6 +156,22 @@ + {% if fast_checkout_client_id_name %} +
+ +
+ +
+
+ {% endif %} + {% if fast_checkout_client_token_name %} +
+ +
+ +
+
+ {% endif %} {% endif %} diff --git a/upload/catalog/controller/extension/payment/paynl.php b/upload/catalog/controller/extension/payment/paynl.php index 34fc405..b2d96b8 100644 --- a/upload/catalog/controller/extension/payment/paynl.php +++ b/upload/catalog/controller/extension/payment/paynl.php @@ -109,12 +109,8 @@ public function addFastCheckoutButtons(&$route, &$data, &$output) { return; } - if (!in_array('cart', $this->config->get('payment_paynl_ideal_button_places'))) { - return; - } - $this->loadResources($output); - $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(['paypal_container_id' => 'paypal-button-container-2']); + $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(['paypal_container_id' => 'paypal-button-container-2'], 'cart'); if (!empty($payMethodsWithFastCheckout)) { $data['fast_checkout_buttons'] = array_filter($payMethodsWithFastCheckout); @@ -130,12 +126,8 @@ public function addFastCheckoutButtons(&$route, &$data, &$output) { } public function addFastCheckoutMiniCartButtons(&$route, &$data, &$output) { - if (!in_array('mini_cart', $this->config->get('payment_paynl_ideal_button_places'))) { - return; - } - $this->loadResources($output); - $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(); + $payMethodsWithFastCheckout = $this->getFastCheckoutButtons([], 'mini_cart'); if (!empty($payMethodsWithFastCheckout)) { $data['fast_checkout_buttons'] = array_filter($payMethodsWithFastCheckout); @@ -151,18 +143,13 @@ public function addFastCheckoutMiniCartButtons(&$route, &$data, &$output) { } public function addFastCheckoutProductPageButtons(&$route, &$data, &$output) { - if (!in_array('product', $this->config->get('payment_paynl_ideal_button_places'))) { - return; - } - $this->loadResources($output); - $paypalContainerId = $this->cart->hasProducts() ? ['paypal_container_id' => 'paypal-button-container-2'] : null; - $payMethodsWithFastCheckout = $this->getFastCheckoutButtons($paypalContainerId); + + $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(['paypal_container_id' => 'paypal-button-container-2'], 'product'); if (!empty($payMethodsWithFastCheckout)) { $data['fast_checkout_buttons'] = array_filter($payMethodsWithFastCheckout); $fastCheckoutButtonsHtml = $this->load->view('payment/fast_checkout_product_buttons', $data); - $fastCheckoutButtonsHtml .= '
'; $textLoading = $data['text_loading']; $buttonCart = $data['button_cart']; @@ -172,7 +159,7 @@ public function addFastCheckoutProductPageButtons(&$route, &$data, &$output) { } } - private function getFastCheckoutButtons($options = array()) { + private function getFastCheckoutButtons($options = array(), $page = null) { $this->load->model('setting/extension'); $results = $this->model_setting_extension->getExtensions('payment'); $payMethodsWithFastCheckout = array(); @@ -181,6 +168,12 @@ private function getFastCheckoutButtons($options = array()) { if ($this->config->get('payment_' . $result['code'] . '_status')) { $fastCheckout = (bool) $this->config->get('payment_' . $result['code'] . '_display_fast_checkout'); + $availablePlaces = $this->config->get('payment_' . $result['code'] . '_button_places'); + + if ($availablePlaces == null || !in_array($page, $availablePlaces)) { + continue; + } + $onlyGuests = (bool) $this->config->get('payment_' . $result['code'] . '_only_guest'); $customerIsLogged = $this->customer->isLogged(); $allowedToProceed = !($onlyGuests && $customerIsLogged); @@ -210,9 +203,7 @@ private function getFastCheckoutButtonLayout($methodCode, $paypalContainerId) { Fast Checkout '; case 'paynl_paypal': - $total_amount = $this->cart->getTotal(); - - return '
'; + return '
'; default: null; } } diff --git a/upload/catalog/controller/extension/payment/paynl_ideal.php b/upload/catalog/controller/extension/payment/paynl_ideal.php index 15aef0c..52a9fcd 100644 --- a/upload/catalog/controller/extension/payment/paynl_ideal.php +++ b/upload/catalog/controller/extension/payment/paynl_ideal.php @@ -10,6 +10,11 @@ class ControllerExtensionPaymentPaynlideal extends Pay_Controller_Payment protected $_paymentMethodName = 'paynl_ideal'; public function initFastCheckout() { + if (empty($this->cart->getProducts())) { + header("Location: " . $this->url->link('checkout/cart')); + exit; + } + $order_data = $this->createBlankFastCheckoutOrder('payment_paynl_ideal_default_shipping'); $response = $this->sendRequest($order_data); @@ -17,8 +22,11 @@ public function initFastCheckout() { if ($this->isAjax()) { die(json_encode($response)); } + if (isset($response['data']['links']['redirect'])) { + header("Location: " . $response['data']['links']['redirect']); + } - header("Location: " . $response['data']['links']['redirect']); + die('SL-code issues'); } /** @@ -50,65 +58,4 @@ public function finishFastCheckout() } die(); } - - public function exchangeFastCheckout() { - $webhookData = $this->request->post; - - $order_id = $webhookData['object']['reference']; - - $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); - - $this->load->model('extension/payment/' . $this->_paymentMethodName); - $modelName = 'model_extension_payment_' . $this->_paymentMethodName; - - $this->load->model('checkout/order'); - - if ($status === Pay_Model::STATUS_COMPLETE) { - $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; - $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; - $customer = $webhookData['object']['checkoutData']['customer']; - - $paymentData = [ - 'firstname' => $customer['firstName'], - 'lastname' => $customer['lastName'], - 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], - 'city' => $billingAddress['city'], - 'postcode' => $billingAddress['zipCode'], - 'country' => $billingAddress['countryCode'], - 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] - ]; - - $shippingData = [ - 'firstname' => $customer['firstName'], - 'lastname' => $customer['lastName'], - 'address_1' => $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'], - 'city' => $shippingAddress['city'], - 'postcode' => $shippingAddress['zipCode'], - 'country' => $shippingAddress['countryCode'] - ]; - - $customerData = [ - 'email' => $customer['email'], - 'phone' => $customer['phone'], - 'lastname' => $customer['lastName'], - 'firstname' => $customer['firstName'], - ]; - - $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); - $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); - - $this->model_checkout_order->addOrderHistory($order_id, 2, 'Order paid via fast checkout.'); - - - $this->response->setOutput(json_encode(['status' => 'success'])); - } - - if ($status === Pay_Model::STATUS_CANCELED) { - $this->model_checkout_order->addOrderHistory($order_id, 7, 'Order cancelled'); - - $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); - - $this->response->setOutput(json_encode(['status' => 'cancelled'])); - } - } } diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index a55c6dd..db50689 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -11,23 +11,47 @@ class ControllerExtensionPaymentPaynlpaypal extends Pay_Controller_Payment public function initFastCheckout() { $order_data = $this->createBlankFastCheckoutOrder('payment_paynl_paypal_default_shipping'); + $this->session->data['fast_checkout_paypal_order'] = $order_data; $totalAmount = $this->cart->getTotal(); + $currency_code = $this->session->data['currency']; + $formatted_total = $this->currency->format($totalAmount, $currency_code, '', false); $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode([ 'order_id' => $order_data['order_id'], - 'total_amount' => number_format($totalAmount, 2, '.', '') + 'total_amount' => number_format($formatted_total, 2, '.', ''), + 'currency' => $currency_code ])); } public function handleResult() { + header('Access-Control-Allow-Origin: *'); + header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); + header('Access-Control-Allow-Headers: Content-Type, Authorization'); + + if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { + header('HTTP/1.1 200 OK'); + exit(); + } + $rawData = file_get_contents('php://input'); $data = json_decode($rawData, true); - $order_data = $this->session->data['fast_checkout_paypal_order']; + if (empty($data['orderID'])) { + $this->response->setOutput(json_encode(['error' => 'Missing orderID'])); + return; + } + + if (isset($this->session->data['fast_checkout_paypal_order'])) { + $order_data = $this->session->data['fast_checkout_paypal_order']; + } else { + $this->response->setOutput(json_encode(['error' => 'Order data not found'])); + return; + } + $order_data['payment_method'] = [ 'id' => $this->_paymentOptionId, 'input' => [ @@ -35,12 +59,232 @@ public function handleResult() ] ]; - //TODO: need to add request to paynl to capture payment and get payer info $response = $this->sendRequest($order_data); - $this->response->setOutput(json_encode($response)); + if (!$response || !isset($response['data']['links']['redirect'])) { + $this->response->setOutput(json_encode(['error' => 'Payment processing failed'])); + return; + } + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode([ + 'status' => 'success', + 'redirect_url' => $response['data']['links']['redirect'] + ])); + } + + /** + * @return void + */ + public function finishFastCheckout() + { + $this->load->model('extension/payment/' . $this->_paymentMethodName); + + $statusCode = $this->request->get['statusCode']; + + $status = Pay_Helper::getStatus($statusCode); + + if (isset($status) && ($status == Pay_Model::STATUS_COMPLETE || $status == Pay_Model::STATUS_PENDING)) { + $this->cart->clear(); + + header("Location: " . $this->url->link('checkout/success')); + } else { + $this->load->language('extension/payment/paynl3'); + + $action = $this->request->get['statusCode']; + if ($action == -90) { + $this->session->data['error'] = $this->language->get('text_cancel'); + } elseif ($action == -63) { + $this->session->data['error'] = $this->language->get('text_denied'); + } + + header("Location: " . $this->url->link('checkout/cart')); + } + die(); + } + + public function cancelPayment() + { + $order = $this->session->data['fast_checkout_paypal_order']; + + $this->load->model('checkout/order'); + $this->model_checkout_order->addOrderHistory($order['order_id'], 7, 'Order cancelled'); + + $this->load->language('extension/payment/paynl3'); + + $this->session->data['error'] = $this->language->get('text_cancel'); + + $this->response->redirect($this->url->link('checkout/cart', '', true)); + } + + public function getButtonConfig() { + $client_id = $this->config->get('payment_paynl_paypal_client_id'); + $currency = $this->session->data['currency']; + $intent = 'capture'; + $appearsIn = $this->config->get('payment_paynl_paypal_button_places'); + $route = isset($this->request->get['route']) ? $this->request->get['route'] : ''; + + $config = [ + 'client_id' => $client_id, + 'intent' => $intent, + 'currency' => $currency, + 'appearsIn' => $appearsIn, + 'current_route' => $route + ]; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($config)); + } + + public function exchangeFastCheckout() { + $rawData = file_get_contents('php://input'); + $webhookData = json_decode($rawData, true); + + if (empty($webhookData)) { + $webhookData = $this->request->post; + } + + $orderId = isset($webhookData['object']['payments'][0]['paymentMethod']['input']['orderId']) + ? $webhookData['object']['payments'][0]['paymentMethod']['input']['orderId'] + : null; + + $accessToken = $this->getAccessToken(); + $paypalOrderDetails = $this->getOrderDetails($orderId, $accessToken); + + if (!$paypalOrderDetails) { + return; + } + + $paypalPayer = [ + 'firstname' => $paypalOrderDetails['payer']['name']['given_name'], + 'lastname' => $paypalOrderDetails['payer']['name']['surname'], + 'countryCode' => $paypalOrderDetails['payer']['address']['country_code'], + ]; + + $shipping = $paypalOrderDetails['purchase_units'][0]['shipping']; + $paypalShipping = [ + 'full_name' => $shipping['name']['full_name'], + 'address_1' => $shipping['address']['address_line_1'], + 'city' => $shipping['address']['admin_area_2'], + 'country' => $shipping['address']['postal_code'], + 'post_code' => $shipping['address']['country_code'], + ]; + + $order_id = $webhookData['object']['reference']; + + $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); + + $this->load->model('extension/payment/' . $this->_paymentMethodName); + $modelName = 'model_extension_payment_' . $this->_paymentMethodName; + + $this->load->model('checkout/order'); + + if ($status === Pay_Model::STATUS_COMPLETE) { + $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; + $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; + $customer = $webhookData['object']['checkoutData']['customer']; + + $paymentData = [ + 'firstname' => $customer['firstName'] ?: $paypalPayer['firstname'], + 'lastname' => $customer['lastName'] ?: $paypalPayer['lastname'], + 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], + 'city' => $billingAddress['city'], + 'postcode' => $billingAddress['zipCode'], + 'country' => $billingAddress['countryCode'] ?: $paypalPayer['countryCode'], + 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] + ]; + + $shippingData = [ + 'firstname' => $customer['firstName'] ?: $paypalShipping['full_name'], + 'lastname' => $customer['lastName'], + 'address_1' => $shippingAddress['streetName'] ? $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'] : $paypalShipping['address_1'], + 'city' => $shippingAddress['city'] ?: $paypalShipping['city'], + 'postcode' => $shippingAddress['zipCode'] ?: $paypalShipping['post_code'], + 'country' => $shippingAddress['countryCode'] ?: $paypalShipping['country'] + ]; + + $customerData = [ + 'email' => $customer['email'] ?: $paypalOrderDetails['payer']['email_address'], + 'phone' => $customer['phone'], + 'lastname' => $customer['lastName'], + 'firstname' => $customer['firstName'], + ]; + + $transactionId = $webhookData['object']['id']; + + $this->$modelName->addTransaction( + $transactionId, + $order_id, + $this->_paymentOptionId, + $webhookData['object']['amount']['value'], + ['type' => 'paypal fast checkout'], + ); + $this->$modelName->updateTransactionStatus($transactionId, $status); + $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); + $this->model_checkout_order->addOrderHistory($order_id, 2, 'Order paid via fast checkout.'); + + $this->response->setOutput(json_encode(['status' => 'success'])); + } + + if ($status === Pay_Model::STATUS_CANCELED) { + $this->model_checkout_order->addOrderHistory($order_id, 7, 'Order cancelled'); + + $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); + + $this->response->setOutput(json_encode(['status' => 'cancelled'])); + } + } + + private function getAccessToken() { + $clientId = $this->config->get('payment_' . $this->_paymentMethodName . '_client_id'); + $clientSecret = $this->config->get('payment_' . $this->_paymentMethodName . '_client_token'); + + if (empty($clientId) || empty($clientSecret)) { + $this->log->write('PayPal Error: Missing Client ID or Client Secret.'); + + return false; + } + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, "https://api-m.sandbox.paypal.com/v1/oauth2/token"); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Accept: application/json", + "Accept-Language: en_US" + ]); + + + curl_setopt($ch, CURLOPT_USERPWD, "$clientId:$clientSecret"); + curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials"); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + $response = curl_exec($ch); + if (curl_errno($ch)) { + throw new Exception(curl_error($ch)); + } + curl_close($ch); + + $result = json_decode($response, true); + + return $result['access_token'] ?? false; + } + + public function getOrderDetails($orderID, $accessToken) { + if (empty($orderID) || empty($accessToken)) { + return false; + } + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "https://api.sandbox.paypal.com/v2/checkout/orders/{$orderID}"); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Content-Type: application/json", + "Authorization: Bearer $accessToken" + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + curl_close($ch); + return json_decode($response, true); } } diff --git a/upload/catalog/model/extension/payment/paynl_ideal.php b/upload/catalog/model/extension/payment/paynl_ideal.php index 4399914..ad5e488 100755 --- a/upload/catalog/model/extension/payment/paynl_ideal.php +++ b/upload/catalog/model/extension/payment/paynl_ideal.php @@ -8,44 +8,4 @@ class ModelExtensionPaymentPaynlIdeal extends Pay_Model { protected $_paymentOptionId = 10; protected $_paymentMethodName = 'paynl_ideal'; - - public function updateOrderAfterWebhook($order_id, $payment_data, $shipping_data, $customer_data) { - $order_query = $this->db->query("SELECT customer_id FROM `" . DB_PREFIX . "order` WHERE order_id = '" . (int)$order_id . "'"); - - if ($order_query->num_rows) { - $query = "UPDATE `" . DB_PREFIX . "order` SET "; - $fields = array(); - - $fields[] = "payment_firstname = '" . $this->db->escape($payment_data['firstname']) . "'"; - $fields[] = "payment_lastname = '" . $this->db->escape($payment_data['lastname']) . "'"; - $fields[] = "payment_address_1 = '" . $this->db->escape($payment_data['address_1']) . "'"; - $fields[] = "payment_city = '" . $this->db->escape($payment_data['city']) . "'"; - $fields[] = "payment_postcode = '" . $this->db->escape($payment_data['postcode']) . "'"; - $fields[] = "payment_country = '" . $this->db->escape($payment_data['country']) . "'"; - $fields[] = "payment_method = '" . $this->db->escape($payment_data['method']) . "'"; - - $fields[] = "shipping_firstname = '" . $this->db->escape($shipping_data['firstname']) . "'"; - $fields[] = "shipping_lastname = '" . $this->db->escape($shipping_data['lastname']) . "'"; - $fields[] = "shipping_address_1 = '" . $this->db->escape($shipping_data['address_1']) . "'"; - $fields[] = "shipping_city = '" . $this->db->escape($shipping_data['city']) . "'"; - $fields[] = "shipping_postcode = '" . $this->db->escape($shipping_data['postcode']) . "'"; - $fields[] = "shipping_country = '" . $this->db->escape($shipping_data['country']) . "'"; - - if ($order_query->row['customer_id'] == 0) { - $fields[] = "firstname = '" . $this->db->escape($customer_data['firstname']) . "'"; - $fields[] = "lastname = '" . $this->db->escape($customer_data['lastname']) . "'"; - $fields[] = "email = '" . $this->db->escape($customer_data['email']) . "'"; - $fields[] = "telephone = '" . $this->db->escape($customer_data['phone']) . "'"; - } - - $query .= implode(", ", $fields); - $query .= " WHERE order_id = '" . (int)$order_id . "'"; - - $this->db->query($query); - - echo "Order information updated successfully."; - } else { - echo "Order not found."; - } - } } diff --git a/upload/catalog/view/theme/default/javascript/paynl.js b/upload/catalog/view/theme/default/javascript/paynl.js index f0311df..8401194 100644 --- a/upload/catalog/view/theme/default/javascript/paynl.js +++ b/upload/catalog/view/theme/default/javascript/paynl.js @@ -1,4 +1,51 @@ jQuery(document).ready(function () { + fetch('index.php?route=extension/payment/paynl_paypal/getButtonConfig') + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then(config => { + if (config && config.client_id) { + return loadPayPalScript(config).then(() => config); + } else { + console.error('Client ID is missing in the configuration'); + return null; + } + }) + .then((config) => { + if (!config) { + console.error('Config is undefined or null'); + return; + } + + const currentRoute = getCurrentRoute(); + + config.appearsIn.forEach(function (location) { + if (location === 'mini_cart') { + waitForElement('#paypal-button-container', function () { + renderPayPalButton('#paypal-button-container'); + }); + } + + if (location === 'product' && currentRoute === 'product/product') { + waitForElement('#paypal-button-container-2', function () { + renderPayPalButton('#paypal-button-container-2'); + }); + } + + if (location === 'cart' && currentRoute === 'checkout/cart') { + waitForElement('#paypal-button-container-2', function () { + renderPayPalButton('#paypal-button-container-2'); + }); + } + }); + }) + .catch(error => { + console.error('Error loading PayPal Button:', error); + }); + $('.fast-checkout-block a').off('click').on('click', function (event) { event.preventDefault(); @@ -10,33 +57,42 @@ jQuery(document).ready(function () { url: 'index.php?route=extension/payment/' + method + '/initFastCheckout', method: 'POST', contentType: 'application/json', - data: JSON.stringify({method: method}), + data: JSON.stringify({ method: method }), success: function (response) { if (typeof response === "string") { response = JSON.parse(response); } - window.location.href = response.data.links.redirect + window.location.href = response.data.links.redirect; }, error: function (xhr, status, error) { console.error('Error:', error.data); } }); }); +}); - waitForElement('#paypal-button-container', function () { - renderPayPalButton('#paypal-button-container'); - }); +function getCurrentRoute() { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get('route') || ''; +} - waitForElement('#paypal-button-container-2', function () { - renderPayPalButton('#paypal-button-container-2'); +function loadPayPalScript(config) { + return new Promise((resolve) => { + if (document.getElementById('paypal-sdk')) return resolve(); + + const script = document.createElement('script'); + script.id = 'paypal-sdk'; + script.src = `https://www.paypal.com/sdk/js?client-id=${config.client_id}&intent=${config.intent}&components=buttons¤cy=${config.currency}`; + script.onload = resolve; + document.head.appendChild(script); }); -}); +} function renderPayPalButton(containerSelector) { - if (!jQuery(containerSelector).is(':empty')) return; // Avoid re-rendering + if (!window.paypal || !jQuery(containerSelector).is(':empty')) return; - const buttonConfig = { + paypal.Buttons({ style: { layout: 'horizontal', color: 'blue', @@ -56,10 +112,12 @@ function renderPayPalButton(containerSelector) { .then(response => response.json()) .then(orderData => { return actions.order.create({ + intent: 'CAPTURE', purchase_units: [{ reference_id: orderData.order_id, amount: { - value: orderData.total_amount + value: orderData.total_amount, + currency_code: orderData.currency } }] }); @@ -71,18 +129,22 @@ function renderPayPalButton(containerSelector) { headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data) + body: JSON.stringify({ orderID: data.orderID }) }) .then(response => response.json()) .then(result => { - console.log(result); - // window.location.href = 'index.php?route=checkout/success'; + if (result.status === 'success' && result.redirect_url) { + window.location.href = result.redirect_url; + } else { + console.error('Payment failed:', result.error); + } }) .catch(error => console.error('Payment failed:', error)); + }, + onCancel: function () { + window.location.href = 'index.php?route=extension/payment/paynl_paypal/cancelPayment'; } - }; - - paypal.Buttons(buttonConfig).render(containerSelector); + }).render(containerSelector); } function waitForElement(selector, callback, interval = 200, maxAttempts = 50) { From c43481ded09c0a13097625243ccb8a4477f35d42 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Mon, 18 Nov 2024 14:19:50 +0200 Subject: [PATCH 03/16] Fix bugs.Implement dynamic PayPal script switching for sandbox and production environments --- .../controller/extension/payment/paynl_paypal.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index db50689..ff2a348 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -247,7 +247,9 @@ private function getAccessToken() { $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, "https://api-m.sandbox.paypal.com/v1/oauth2/token"); + $testMode = $this->config->get('payment_paynl_general_testmode'); + $url = $testMode ? "https://api-m.sandbox.paypal.com/v1/oauth2/token": "https://api-m.paypal.com/v1/oauth2/token"; + curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Accept: application/json", "Accept-Language: en_US" @@ -275,7 +277,10 @@ public function getOrderDetails($orderID, $accessToken) { } $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, "https://api.sandbox.paypal.com/v2/checkout/orders/{$orderID}"); + + $testMode = $this->config->get('payment_paynl_general_testmode'); + $url = $testMode ? "https://api.sandbox.paypal.com/v2/checkout/orders/{$orderID}": "https://api.paypal.com/v2/checkout/orders/{$orderID}"; + curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", "Authorization: Bearer $accessToken" From ab435da1a6d47946b57324d34d24496503a05f69 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Thu, 21 Nov 2024 16:40:50 +0200 Subject: [PATCH 04/16] Fix bugs. According changes for Ideal fc --- .../controller/extension/payment/paynl.php | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl.php b/upload/catalog/controller/extension/payment/paynl.php index d622ac4..7e43fdc 100644 --- a/upload/catalog/controller/extension/payment/paynl.php +++ b/upload/catalog/controller/extension/payment/paynl.php @@ -105,8 +105,7 @@ public function paynlDoAutoCapture($apiToken, $serviceId, $transactionId, $order } public function addFastCheckoutButtons(&$route, &$data, &$output) { - $configButtonPlaces = $this->config->get('payment_paynl_ideal_button_places'); - if (!is_array($configButtonPlaces) || !in_array('Cart', $configButtonPlaces)) { + if (!$this->isButtonAllowed('cart')) { return; } @@ -131,8 +130,7 @@ public function addFastCheckoutButtons(&$route, &$data, &$output) { } public function addFastCheckoutMiniCartButtons(&$route, &$data, &$output) { - $configButtonPlaces = $this->config->get('payment_paynl_ideal_button_places'); - if (!is_array($configButtonPlaces) || !in_array('mini_cart', $configButtonPlaces)) { + if (!$this->isButtonAllowed('mini_cart')) { return; } @@ -153,10 +151,10 @@ public function addFastCheckoutMiniCartButtons(&$route, &$data, &$output) { } public function addFastCheckoutProductPageButtons(&$route, &$data, &$output) { - $configButtonPlaces = $this->config->get('payment_paynl_ideal_button_places'); - if (!is_array($configButtonPlaces) || !in_array('product', $configButtonPlaces)) { + if (!$this->isButtonAllowed('product')) { return; } + $this->loadResources($output); $payMethodsWithFastCheckout = $this->getFastCheckoutButtons(['paypal_container_id' => 'paypal-button-container-2'], 'product'); @@ -228,4 +226,25 @@ private function loadResources(&$output) { $output = str_replace('
', '
' . $styleTag . $scriptTag, $output); } + + private function isButtonAllowed($placeName) { + $configKeys = $this->getButtonPlacesConfigKeys(); + + foreach ($configKeys as $configKey) { + $configButtonPlaces = $this->config->get($configKey); + + if (is_array($configButtonPlaces) && in_array($placeName, $configButtonPlaces)) { + return true; + } + } + + return false; + } + + private function getButtonPlacesConfigKeys() { + return [ + 'payment_paynl_ideal_button_places', + 'payment_paynl_paypal_button_places', + ]; + } } From 66919d14a1a45b288dd676ea874a2eb4ec504f79 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Mon, 2 Dec 2024 13:21:33 +0200 Subject: [PATCH 05/16] Resolve conflicts after merge master. Fix responses for webhooks --- .../extension/payment/paynl_paypal.php | 113 ++++++++++-------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index ff2a348..501a887 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -179,59 +179,72 @@ public function exchangeFastCheckout() { $this->load->model('checkout/order'); - if ($status === Pay_Model::STATUS_COMPLETE) { - $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; - $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; - $customer = $webhookData['object']['checkoutData']['customer']; - - $paymentData = [ - 'firstname' => $customer['firstName'] ?: $paypalPayer['firstname'], - 'lastname' => $customer['lastName'] ?: $paypalPayer['lastname'], - 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], - 'city' => $billingAddress['city'], - 'postcode' => $billingAddress['zipCode'], - 'country' => $billingAddress['countryCode'] ?: $paypalPayer['countryCode'], - 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] - ]; - - $shippingData = [ - 'firstname' => $customer['firstName'] ?: $paypalShipping['full_name'], - 'lastname' => $customer['lastName'], - 'address_1' => $shippingAddress['streetName'] ? $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'] : $paypalShipping['address_1'], - 'city' => $shippingAddress['city'] ?: $paypalShipping['city'], - 'postcode' => $shippingAddress['zipCode'] ?: $paypalShipping['post_code'], - 'country' => $shippingAddress['countryCode'] ?: $paypalShipping['country'] - ]; - - $customerData = [ - 'email' => $customer['email'] ?: $paypalOrderDetails['payer']['email_address'], - 'phone' => $customer['phone'], - 'lastname' => $customer['lastName'], - 'firstname' => $customer['firstName'], - ]; - - $transactionId = $webhookData['object']['id']; - - $this->$modelName->addTransaction( - $transactionId, - $order_id, - $this->_paymentOptionId, - $webhookData['object']['amount']['value'], - ['type' => 'paypal fast checkout'], - ); - $this->$modelName->updateTransactionStatus($transactionId, $status); - $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); - $this->model_checkout_order->addOrderHistory($order_id, 2, 'Order paid via fast checkout.'); - - $this->response->setOutput(json_encode(['status' => 'success'])); - } + try { + if ($status === Pay_Model::STATUS_COMPLETE) { + $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; + $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; + $customer = $webhookData['object']['checkoutData']['customer']; + + $paymentData = [ + 'firstname' => $customer['firstName'] ?: $paypalPayer['firstname'], + 'lastname' => $customer['lastName'] ?: $paypalPayer['lastname'], + 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], + 'city' => $billingAddress['city'], + 'postcode' => $billingAddress['zipCode'], + 'country' => $billingAddress['countryCode'] ?: $paypalPayer['countryCode'], + 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] + ]; + + $shippingData = [ + 'firstname' => $customer['firstName'] ?: $paypalShipping['full_name'], + 'lastname' => $customer['lastName'], + 'address_1' => $shippingAddress['streetName'] ? $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'] : $paypalShipping['address_1'], + 'city' => $shippingAddress['city'] ?: $paypalShipping['city'], + 'postcode' => $shippingAddress['zipCode'] ?: $paypalShipping['post_code'], + 'country' => $shippingAddress['countryCode'] ?: $paypalShipping['country'] + ]; + + $customerData = [ + 'email' => $customer['email'] ?: $paypalOrderDetails['payer']['email_address'], + 'phone' => $customer['phone'], + 'lastname' => $customer['lastName'], + 'firstname' => $customer['firstName'], + ]; + + $transactionId = $webhookData['object']['id']; + + $this->$modelName->addTransaction( + $transactionId, + $order_id, + $this->_paymentOptionId, + $webhookData['object']['amount']['value'], + ['type' => 'paypal fast checkout'], + ); + $this->$modelName->updateTransactionStatus($transactionId, $status); + + $result = $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); + if ($result === false) { + die("FALSE| Order not found"); + } + + $this->model_checkout_order->addOrderHistory($order_id, 2, 'Order paid via fast checkout.'); + + die("TRUE| processed successfully"); + } - if ($status === Pay_Model::STATUS_CANCELED) { - $this->model_checkout_order->addOrderHistory($order_id, 7, 'Order cancelled'); + if ($status === Pay_Model::STATUS_CANCELED) { + $this->model_checkout_order->addOrderHistory($order_id, 7, 'Order cancelled'); - $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); + $this->$modelName->updateTransactionStatus($webhookData['object']['id'], $status); - $this->response->setOutput(json_encode(['status' => 'cancelled'])); + die("TRUE|Order cancelled"); + } + } catch (Pay_Api_Exception $e) { + die("FALSE| Api Error: " . $e->getMessage()); + } catch (Pay_Exception $e) { + die("FALSE| Plugin Error: " . $e->getMessage()); + } catch (Exception $e) { + die("FALSE| Unknown Error: " . $e->getMessage()); } } From 369850b5daf8ab98f9eaa9d3458c26fb4968884d Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Tue, 3 Dec 2024 17:37:10 +0200 Subject: [PATCH 06/16] Fix Ideal button bug when click in the product page with empty cart - Add timeout --- .../view/theme/default/javascript/paynl.js | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/upload/catalog/view/theme/default/javascript/paynl.js b/upload/catalog/view/theme/default/javascript/paynl.js index 8401194..5f65369 100644 --- a/upload/catalog/view/theme/default/javascript/paynl.js +++ b/upload/catalog/view/theme/default/javascript/paynl.js @@ -52,23 +52,26 @@ jQuery(document).ready(function () { $(this).disabled = true; $('#button-cart').click(); - var method = $(this).data('method'); - $.ajax({ - url: 'index.php?route=extension/payment/' + method + '/initFastCheckout', - method: 'POST', - contentType: 'application/json', - data: JSON.stringify({ method: method }), - success: function (response) { - if (typeof response === "string") { - response = JSON.parse(response); - } + const method = $(this).data('method'); - window.location.href = response.data.links.redirect; - }, - error: function (xhr, status, error) { - console.error('Error:', error.data); - } - }); + setTimeout(() => { + $.ajax({ + url: 'index.php?route=extension/payment/' + method + '/initFastCheckout', + method: 'POST', + contentType: 'application/json', + data: JSON.stringify({ method: method }), + success: function (response) { + if (typeof response === "string") { + response = JSON.parse(response); + } + + window.location.href = response.data.links.redirect; + }, + error: function (xhr, status, error) { + console.error('Error:', error.data); + } + }); + }, 500); }); }); From 3a0258111e2c7bc44c6427dc7ae92f5a92da773f Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Thu, 5 Dec 2024 12:32:24 +0200 Subject: [PATCH 07/16] Fix Paypal button --- upload/Pay/Api/FastCheckout.php | 17 ++++++++++++++++- upload/Pay/Controller/Payment.php | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/upload/Pay/Api/FastCheckout.php b/upload/Pay/Api/FastCheckout.php index 45846fe..a0658c6 100644 --- a/upload/Pay/Api/FastCheckout.php +++ b/upload/Pay/Api/FastCheckout.php @@ -11,6 +11,7 @@ class Pay_Api_FastCheckout extends Pay_Api private $_testmode; private $_orderNumber; private $_amount; + private $_currency; private $_description; private $_reference; private $_optimize; @@ -54,6 +55,17 @@ public function setAmount($amount) } } + /** + * Set the currency of the transaction + * + * @param string $currency + * @return void + */ + public function setCurrency($currency) + { + $this->_currency = $currency; + } + /** * @param string $description * @return void @@ -163,7 +175,10 @@ protected function _getPostData() $postData = [ 'serviceId' => $this->_serviceId, - 'amount' => ['value' => $this->_amount], + 'amount' => [ + 'value' => $this->_amount, + 'currency' => $this->_currency, + ], 'description' => $this->_description, 'reference' => $this->_reference, 'optimize' => $this->_optimize, diff --git a/upload/Pay/Controller/Payment.php b/upload/Pay/Controller/Payment.php index fafb039..00ba05e 100755 --- a/upload/Pay/Controller/Payment.php +++ b/upload/Pay/Controller/Payment.php @@ -570,6 +570,7 @@ protected function sendRequest($orderData) $amount = round($orderData['total'] * 100 * $orderData['currency_value']); $apiFastCheckout->setAmount($amount); + $apiFastCheckout->setCurrency($orderData['currency_code']); //Producten toevoegen foreach ($this->cart->getProducts() as $product) { From 10db80b81f75232e5f6ad408b89948395ec58292 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Fri, 6 Dec 2024 10:59:49 +0200 Subject: [PATCH 08/16] Fix bugs. Add observeMiniCartChanges function, add setTimeout function --- .../view/theme/default/javascript/paynl.js | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/upload/catalog/view/theme/default/javascript/paynl.js b/upload/catalog/view/theme/default/javascript/paynl.js index 5f65369..625b693 100644 --- a/upload/catalog/view/theme/default/javascript/paynl.js +++ b/upload/catalog/view/theme/default/javascript/paynl.js @@ -59,7 +59,7 @@ jQuery(document).ready(function () { url: 'index.php?route=extension/payment/' + method + '/initFastCheckout', method: 'POST', contentType: 'application/json', - data: JSON.stringify({ method: method }), + data: JSON.stringify({method: method}), success: function (response) { if (typeof response === "string") { response = JSON.parse(response); @@ -73,6 +73,8 @@ jQuery(document).ready(function () { }); }, 500); }); + + observeMiniCartChanges(); }); function getCurrentRoute() { @@ -106,11 +108,15 @@ function renderPayPalButton(containerSelector) { createOrder: function (data, actions) { $('#button-cart').click(); - return fetch('index.php?route=extension/payment/paynl_paypal/initFastCheckout', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - } + return new Promise((resolve) => { + setTimeout(() => { + resolve(fetch('index.php?route=extension/payment/paynl_paypal/initFastCheckout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + })); + }, 500); }) .then(response => response.json()) .then(orderData => { @@ -132,7 +138,7 @@ function renderPayPalButton(containerSelector) { headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ orderID: data.orderID }) + body: JSON.stringify({orderID: data.orderID}) }) .then(response => response.json()) .then(result => { @@ -166,3 +172,27 @@ function waitForElement(selector, callback, interval = 200, maxAttempts = 50) { checkElement(); } + +function observeMiniCartChanges() { + const miniCart = document.querySelector('#cart'); + + if (!miniCart) { + console.error('Mini-cart element not found'); + return; + } + + const observer = new MutationObserver((mutationsList) => { + for (let mutation of mutationsList) { + if (mutation.type === 'childList' || mutation.type === 'subtree') { + if (jQuery('#paypal-button-container').is(':empty')) { + renderPayPalButton('#paypal-button-container'); + } + } + } + }); + + observer.observe(miniCart, { + childList: true, + subtree: true + }); +} From 129a29cd116d7b2933f429a5341674177cb97e37 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Fri, 6 Dec 2024 16:05:24 +0200 Subject: [PATCH 09/16] Add throwing error instead of just return nothing --- upload/catalog/controller/extension/payment/paynl_paypal.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index 501a887..551bb53 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -136,6 +136,7 @@ public function getButtonConfig() { $this->response->setOutput(json_encode($config)); } + /** @throws Pay_Api_Exception */ public function exchangeFastCheckout() { $rawData = file_get_contents('php://input'); $webhookData = json_decode($rawData, true); @@ -152,7 +153,7 @@ public function exchangeFastCheckout() { $paypalOrderDetails = $this->getOrderDetails($orderId, $accessToken); if (!$paypalOrderDetails) { - return; + throw new Pay_Api_Exception('Paypal order details not received'); } $paypalPayer = [ From d54966130185f4d7082de39fce6c88f0b6ec18ce Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Tue, 10 Dec 2024 15:54:28 +0200 Subject: [PATCH 10/16] Fix bugs --- upload/Pay/Model.php | 4 ++-- upload/catalog/controller/extension/payment/paynl_paypal.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/upload/Pay/Model.php b/upload/Pay/Model.php index 3cf95cb..378fe8a 100755 --- a/upload/Pay/Model.php +++ b/upload/Pay/Model.php @@ -525,9 +525,9 @@ public function updateOrderAfterWebhook($order_id, $payment_data, $shipping_data $this->db->query($query); - echo "Order information updated successfully."; + echo "TRUE| Order information updated successfully."; } else { - echo "Order not found."; + echo "FALSE| Order not found."; } } } diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index 551bb53..60178f9 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -153,7 +153,7 @@ public function exchangeFastCheckout() { $paypalOrderDetails = $this->getOrderDetails($orderId, $accessToken); if (!$paypalOrderDetails) { - throw new Pay_Api_Exception('Paypal order details not received'); + die("FALSE| Paypal order details not received"); } $paypalPayer = [ From 66f3d484eec04bd44a0d6c26752ece99ea2796e7 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Tue, 10 Dec 2024 17:38:18 +0200 Subject: [PATCH 11/16] Fix bugs. Add condition to check if transaction already added --- .../extension/payment/paynl_paypal.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index 60178f9..f06c8d3 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -214,13 +214,17 @@ public function exchangeFastCheckout() { $transactionId = $webhookData['object']['id']; - $this->$modelName->addTransaction( - $transactionId, - $order_id, - $this->_paymentOptionId, - $webhookData['object']['amount']['value'], - ['type' => 'paypal fast checkout'], - ); + $transaction = $this->$modelName->getTransaction($transactionId); + + if(empty($transaction)) { + $this->$modelName->addTransaction( + $transactionId, + $order_id, + $this->_paymentOptionId, + $webhookData['object']['amount']['value'], + ['type' => 'paypal fast checkout'], + ); + } $this->$modelName->updateTransactionStatus($transactionId, $status); $result = $this->$modelName->updateOrderAfterWebhook($order_id, $paymentData, $shippingData, $customerData); From 09e92d4e4d32c2e13f5691f573493426e699fc17 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Tue, 10 Dec 2024 18:06:43 +0200 Subject: [PATCH 12/16] Fix bugs. Change return --- upload/Pay/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upload/Pay/Model.php b/upload/Pay/Model.php index 378fe8a..198cc51 100755 --- a/upload/Pay/Model.php +++ b/upload/Pay/Model.php @@ -525,9 +525,9 @@ public function updateOrderAfterWebhook($order_id, $payment_data, $shipping_data $this->db->query($query); - echo "TRUE| Order information updated successfully."; + return true; } else { - echo "FALSE| Order not found."; + return false; } } } From de64dc7bac734f65caebe67b91c2ad0d4673a852 Mon Sep 17 00:00:00 2001 From: inozemtsevpaynl Date: Wed, 11 Dec 2024 09:48:12 +0200 Subject: [PATCH 13/16] Refactoring --- .../catalog/controller/extension/payment/paynl_paypal.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index f06c8d3..b9dc585 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -266,7 +266,8 @@ private function getAccessToken() { $ch = curl_init(); $testMode = $this->config->get('payment_paynl_general_testmode'); - $url = $testMode ? "https://api-m.sandbox.paypal.com/v1/oauth2/token": "https://api-m.paypal.com/v1/oauth2/token"; + $domain = $testMode ? 'https://api-m.sandbox.paypal.com': 'https://api-m.paypal.com'; + $url = "{$domain}/v1/oauth2/token"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Accept: application/json", @@ -297,7 +298,9 @@ public function getOrderDetails($orderID, $accessToken) { $ch = curl_init(); $testMode = $this->config->get('payment_paynl_general_testmode'); - $url = $testMode ? "https://api.sandbox.paypal.com/v2/checkout/orders/{$orderID}": "https://api.paypal.com/v2/checkout/orders/{$orderID}"; + $domain = $testMode ? "https://api.sandbox.paypal.com": "https://api.paypal.com"; + $url = "{$domain}/v2/checkout/orders/{$orderID}"; + curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", From df50a4031176e3de1533e7f9ab0e72f76d5126b6 Mon Sep 17 00:00:00 2001 From: kevinverschoor <61683999+kevinverschoor@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:15:21 +0100 Subject: [PATCH 14/16] Add Api check to see if transaction exists --- .../controller/extension/payment/paynl_ideal.php | 15 +++++++++++++++ .../controller/extension/payment/paynl_paypal.php | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/upload/catalog/controller/extension/payment/paynl_ideal.php b/upload/catalog/controller/extension/payment/paynl_ideal.php index 7313973..d61a177 100644 --- a/upload/catalog/controller/extension/payment/paynl_ideal.php +++ b/upload/catalog/controller/extension/payment/paynl_ideal.php @@ -77,6 +77,21 @@ public function exchangeFastCheckout() $order_id = $webhookData['object']['reference']; + $this->load->model('setting/setting'); + $apiToken = $this->model_setting_setting->getSettingValue('payment_paynl_general_apitoken'); + $serviceId = $this->model_setting_setting->getSettingValue('payment_paynl_general_serviceid'); + $transactionId = $webhookData['object']['orderId']; + + try { + $apiInfo = new Pay_Api_Info(); + $apiInfo->setApiToken($apiToken); + $apiInfo->setServiceId($serviceId); + $apiInfo->setTransactionId($transactionId); + $apiInfo->doRequest(); + } catch (\Exception $e) { + die('FALSE| Error fetching transaction. ' . $e->getMessage()); + } + $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); $this->load->model('extension/payment/' . $this->_paymentMethodName); diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index b9dc585..cffc0c9 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -149,6 +149,21 @@ public function exchangeFastCheckout() { ? $webhookData['object']['payments'][0]['paymentMethod']['input']['orderId'] : null; + $this->load->model('setting/setting'); + $apiToken = $this->model_setting_setting->getSettingValue('payment_paynl_general_apitoken'); + $serviceId = $this->model_setting_setting->getSettingValue('payment_paynl_general_serviceid'); + $transactionId = $webhookData['object']['orderId']; + + try { + $apiInfo = new Pay_Api_Info(); + $apiInfo->setApiToken($apiToken); + $apiInfo->setServiceId($serviceId); + $apiInfo->setTransactionId($transactionId); + $apiInfo->doRequest(); + } catch (\Exception $e) { + die('FALSE| Error fetching transaction. ' . $e->getMessage()); + } + $accessToken = $this->getAccessToken(); $paypalOrderDetails = $this->getOrderDetails($orderId, $accessToken); From c3b8345d1c282e148b10acaf2361d14f3698a976 Mon Sep 17 00:00:00 2001 From: kevinverschoor <61683999+kevinverschoor@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:13:14 +0100 Subject: [PATCH 15/16] Get all address info from Paypal --- .../extension/payment/paynl_paypal.php | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index cffc0c9..c7e47fa 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -197,35 +197,31 @@ public function exchangeFastCheckout() { try { if ($status === Pay_Model::STATUS_COMPLETE) { - $billingAddress = $webhookData['object']['checkoutData']['billingAddress']; - $shippingAddress = $webhookData['object']['checkoutData']['shippingAddress']; - $customer = $webhookData['object']['checkoutData']['customer']; - $paymentData = [ - 'firstname' => $customer['firstName'] ?: $paypalPayer['firstname'], - 'lastname' => $customer['lastName'] ?: $paypalPayer['lastname'], - 'address_1' => $billingAddress['streetName'] . ' ' . $billingAddress['streetNumber'], - 'city' => $billingAddress['city'], - 'postcode' => $billingAddress['zipCode'], - 'country' => $billingAddress['countryCode'] ?: $paypalPayer['countryCode'], + 'firstname' => $paypalPayer['firstname'], + 'lastname' => $paypalPayer['lastname'], + 'address_1' => $paypalShipping['address_1'], + 'city' => $paypalShipping['city'], + 'postcode' => $paypalShipping['post_code'], + 'country' => $paypalPayer['countryCode'], 'method' => $webhookData['object']['payments'][0]['paymentMethod']['id'] ]; $shippingData = [ - 'firstname' => $customer['firstName'] ?: $paypalShipping['full_name'], - 'lastname' => $customer['lastName'], - 'address_1' => $shippingAddress['streetName'] ? $shippingAddress['streetName'] . ' ' . $shippingAddress['streetNumber'] : $paypalShipping['address_1'], - 'city' => $shippingAddress['city'] ?: $paypalShipping['city'], - 'postcode' => $shippingAddress['zipCode'] ?: $paypalShipping['post_code'], - 'country' => $shippingAddress['countryCode'] ?: $paypalShipping['country'] + 'firstname' => $paypalPayer['firstname'], + 'lastname' => $paypalPayer['lastname'], + 'address_1' => $paypalShipping['address_1'], + 'city' => $paypalShipping['city'], + 'postcode' => $paypalShipping['post_code'], + 'country' => $paypalShipping['country'] ]; $customerData = [ - 'email' => $customer['email'] ?: $paypalOrderDetails['payer']['email_address'], - 'phone' => $customer['phone'], - 'lastname' => $customer['lastName'], - 'firstname' => $customer['firstName'], - ]; + 'email' => $paypalOrderDetails['payer']['email_address'], + 'phone' => '', + 'lastname' => $paypalPayer['lastname'], + 'firstname' => $paypalPayer['firstname'], + ]; $transactionId = $webhookData['object']['id']; From f28c3f6c0736841d05bab0636b6e699f7394e3ef Mon Sep 17 00:00:00 2001 From: kevinverschoor <61683999+kevinverschoor@users.noreply.github.com> Date: Mon, 16 Dec 2024 10:43:26 +0100 Subject: [PATCH 16/16] Check status from Api request --- .../controller/extension/payment/paynl_ideal.php | 7 +++---- .../controller/extension/payment/paynl_paypal.php | 11 +++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/upload/catalog/controller/extension/payment/paynl_ideal.php b/upload/catalog/controller/extension/payment/paynl_ideal.php index d61a177..9d68301 100644 --- a/upload/catalog/controller/extension/payment/paynl_ideal.php +++ b/upload/catalog/controller/extension/payment/paynl_ideal.php @@ -87,12 +87,11 @@ public function exchangeFastCheckout() $apiInfo->setApiToken($apiToken); $apiInfo->setServiceId($serviceId); $apiInfo->setTransactionId($transactionId); - $apiInfo->doRequest(); + $infoResult = $apiInfo->doRequest(); + $status = Pay_Helper::getStatus($infoResult['paymentDetails']['state']); } catch (\Exception $e) { die('FALSE| Error fetching transaction. ' . $e->getMessage()); - } - - $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); + } $this->load->model('extension/payment/' . $this->_paymentMethodName); $modelName = 'model_extension_payment_' . $this->_paymentMethodName; diff --git a/upload/catalog/controller/extension/payment/paynl_paypal.php b/upload/catalog/controller/extension/payment/paynl_paypal.php index c7e47fa..3443870 100755 --- a/upload/catalog/controller/extension/payment/paynl_paypal.php +++ b/upload/catalog/controller/extension/payment/paynl_paypal.php @@ -154,15 +154,16 @@ public function exchangeFastCheckout() { $serviceId = $this->model_setting_setting->getSettingValue('payment_paynl_general_serviceid'); $transactionId = $webhookData['object']['orderId']; - try { + try { $apiInfo = new Pay_Api_Info(); $apiInfo->setApiToken($apiToken); $apiInfo->setServiceId($serviceId); $apiInfo->setTransactionId($transactionId); - $apiInfo->doRequest(); + $infoResult = $apiInfo->doRequest(); + $status = Pay_Helper::getStatus($infoResult['paymentDetails']['state']); } catch (\Exception $e) { - die('FALSE| Error fetching transaction. ' . $e->getMessage()); - } + die('FALSE| Error fetching transaction. ' . $e->getMessage()); + } $accessToken = $this->getAccessToken(); $paypalOrderDetails = $this->getOrderDetails($orderId, $accessToken); @@ -188,8 +189,6 @@ public function exchangeFastCheckout() { $order_id = $webhookData['object']['reference']; - $status = Pay_Helper::getStatus($webhookData['object']['status']['code']); - $this->load->model('extension/payment/' . $this->_paymentMethodName); $modelName = 'model_extension_payment_' . $this->_paymentMethodName;