From d6fe635394c0dda512cbf0d4c3df50ba85e808c2 Mon Sep 17 00:00:00 2001 From: TheCartpenter Date: Sat, 25 May 2024 15:06:47 -0400 Subject: [PATCH] Updated PayPal Checkout payment extension --- .../controller/extension/payment/paypal.php | 3363 ++++++++----- .../en-gb/extension/payment/paypal.php | 73 +- .../admin/model/extension/payment/paypal.php | 545 +- .../paypal/icon-message-configurator.svg | 41 + .../payment/paypal/icon-message-setting.svg | 43 + upload/admin/view/javascript/paypal/paypal.js | 268 +- upload/admin/view/stylesheet/paypal/card.css | 138 +- .../admin/view/stylesheet/paypal/paypal.css | 62 +- .../payment/paypal/applepay_button.twig | 501 +- .../extension/payment/paypal/auth.twig | 212 +- .../extension/payment/paypal/button.twig | 622 ++- .../extension/payment/paypal/card.twig | 337 +- .../extension/payment/paypal/contact.twig | 296 +- .../extension/payment/paypal/dashboard.twig | 264 +- .../extension/payment/paypal/general.twig | 411 +- .../payment/paypal/googlepay_button.twig | 497 +- .../payment/paypal/message_configurator.twig | 193 + .../payment/paypal/message_setting.twig | 145 + .../extension/payment/paypal/order.twig | 437 +- .../payment/paypal/order_status.twig | 136 +- .../extension/payment/paypal/recurring.twig | 81 + .../controller/extension/payment/paypal.php | 4378 ++++++++++------- .../extension/payment/paypal_applepay.php | 166 +- .../extension/payment/paypal_googlepay.php | 166 +- .../extension/payment/paypal_paylater.php | 158 +- .../controller/extension/recurring/paypal.php | 72 + .../en-gb/extension/payment/paypal.php | 193 +- .../en-gb/extension/recurring/paypal.php | 2 +- .../model/extension/payment/paypal.php | 1175 ++--- .../extension/payment/paypal_applepay.php | 34 +- .../extension/payment/paypal_googlepay.php | 32 +- .../extension/payment/paypal_paylater.php | 47 +- .../catalog/view/javascript/paypal/paypal.js | 516 +- .../view/theme/default/image/paypal/card.svg | 430 ++ .../theme/default/stylesheet/paypal/card.css | 249 +- .../default/stylesheet/paypal/paypal.css | 21 + .../extension/payment/paypal/confirm.twig | 1254 +++-- .../extension/payment/paypal/failure.twig | 27 + .../extension/payment/paypal/message.twig | 7 +- .../payment/paypal/payment_address.twig | 582 ++- .../extension/payment/paypal/paypal.twig | 153 +- .../payment/paypal/paypal_applepay.twig | 66 +- .../payment/paypal/paypal_applepay_modal.twig | 36 +- .../payment/paypal/paypal_googlepay.twig | 66 +- .../paypal/paypal_googlepay_modal.twig | 36 +- .../payment/paypal/paypal_modal.twig | 117 +- .../payment/paypal/paypal_paylater.twig | 66 +- .../payment/paypal/paypal_paylater_modal.twig | 36 +- .../payment/paypal/shipping_address.twig | 375 +- .../template/extension/recurring/paypal.twig | 81 + upload/system/config/paypal.php | 1606 +++--- upload/system/config/paypal_carrier.php | 1392 ++++++ upload/system/library/paypal/paypal.php | 602 ++- 53 files changed, 13918 insertions(+), 8888 deletions(-) create mode 100644 upload/admin/view/image/payment/paypal/icon-message-configurator.svg create mode 100644 upload/admin/view/image/payment/paypal/icon-message-setting.svg create mode 100644 upload/admin/view/template/extension/payment/paypal/message_configurator.twig create mode 100644 upload/admin/view/template/extension/payment/paypal/message_setting.twig create mode 100644 upload/admin/view/template/extension/payment/paypal/recurring.twig create mode 100644 upload/catalog/controller/extension/recurring/paypal.php create mode 100644 upload/catalog/view/theme/default/image/paypal/card.svg create mode 100644 upload/catalog/view/theme/default/template/extension/payment/paypal/failure.twig create mode 100644 upload/catalog/view/theme/default/template/extension/recurring/paypal.twig create mode 100644 upload/system/config/paypal_carrier.php diff --git a/upload/admin/controller/extension/payment/paypal.php b/upload/admin/controller/extension/payment/paypal.php index e5bdc04ad..de714b764 100644 --- a/upload/admin/controller/extension/payment/paypal.php +++ b/upload/admin/controller/extension/payment/paypal.php @@ -1,21 +1,16 @@ - */ - private array $error = []; - - /** - * Index - * - * @return void - */ - public function index(): void { + private $error = array(); + + public function __construct($registry) { + parent::__construct($registry); + + if (empty($this->config->get('paypal_version')) || (!empty($this->config->get('paypal_version')) && ($this->config->get('paypal_version') < '3.1.0'))) { + $this->update(); + } + } + + public function index() { if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $server = HTTPS_SERVER; $catalog = HTTPS_CATALOG; @@ -23,116 +18,123 @@ public function index(): void { $server = HTTP_SERVER; $catalog = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - - if (isset($this->session->data['environment']) && isset($this->session->data['authorization_code']) && isset($this->session->data['shared_id']) && isset($this->session->data['seller_nonce']) && isset($this->request->get['merchantIdInPayPal'])) { + + $cache_data = $this->cache->get('paypal'); + + $this->cache->delete('paypal'); + + if (!empty($cache_data['environment']) && !empty($cache_data['authorization_code']) && !empty($cache_data['shared_id']) && !empty($cache_data['seller_nonce']) && !empty($this->request->get['merchantIdInPayPal'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - - $environment = $this->session->data['environment']; - + + $environment = $cache_data['environment']; + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $this->session->data['shared_id'], - 'environment' => $environment, + + $paypal_info = array( + 'client_id' => $cache_data['shared_id'], + 'environment' => $environment, 'partner_attribution_id' => $config_setting['partner'][$environment]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ - 'grant_type' => 'authorization_code', - 'code' => $this->session->data['authorization_code'], - 'code_verifier' => $this->session->data['seller_nonce'] - ]; - + + $token_info = array( + 'grant_type' => 'authorization_code', + 'code' => $cache_data['authorization_code'], + 'code_verifier' => $cache_data['seller_nonce'] + ); + $paypal->setAccessToken($token_info); - + $result = $paypal->getSellerCredentials($config_setting['partner'][$environment]['partner_id']); - + $client_id = ''; $secret = ''; - + if (isset($result['client_id']) && isset($result['client_secret'])) { $client_id = $result['client_id']; $secret = $result['client_secret']; } - - $paypal_info = [ - 'partner_id' => $config_setting['partner'][$environment]['partner_id'], - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $config_setting['partner'][$environment]['partner_id'], + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $config_setting['partner'][$environment]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + + $order_history_token = sha1(uniqid(mt_rand(), 1)); + $callback_token = sha1(uniqid(mt_rand(), 1)); $webhook_token = sha1(uniqid(mt_rand(), 1)); $cron_token = sha1(uniqid(mt_rand(), 1)); - - $webhook_info = [ - 'url' => $catalog . 'index.php?route=extension/payment/paypal&webhook_token=' . $webhook_token, - 'event_types' => [ - ['name' => 'PAYMENT.AUTHORIZATION.CREATED'], - ['name' => 'PAYMENT.AUTHORIZATION.VOIDED'], - ['name' => 'PAYMENT.CAPTURE.COMPLETED'], - ['name' => 'PAYMENT.CAPTURE.DENIED'], - ['name' => 'PAYMENT.CAPTURE.PENDING'], - ['name' => 'PAYMENT.CAPTURE.REFUNDED'], - ['name' => 'PAYMENT.CAPTURE.REVERSED'], - ['name' => 'CHECKOUT.ORDER.COMPLETED'] - ] - ]; - + + $webhook_info = array( + 'url' => $catalog . 'index.php?route=extension/payment/paypal&webhook_token=' . $webhook_token, + 'event_types' => array( + array('name' => 'PAYMENT.AUTHORIZATION.CREATED'), + array('name' => 'PAYMENT.AUTHORIZATION.VOIDED'), + array('name' => 'PAYMENT.CAPTURE.COMPLETED'), + array('name' => 'PAYMENT.CAPTURE.DENIED'), + array('name' => 'PAYMENT.CAPTURE.PENDING'), + array('name' => 'PAYMENT.CAPTURE.REFUNDED'), + array('name' => 'PAYMENT.CAPTURE.REVERSED'), + array('name' => 'CHECKOUT.ORDER.COMPLETED'), + array('name' => 'VAULT.PAYMENT-TOKEN.CREATED') + ) + ); + $result = $paypal->createWebhook($webhook_info); - + $webhook_id = ''; - + if (isset($result['id'])) { $webhook_id = $result['id']; } - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + $merchant_id = $this->request->get['merchantIdInPayPal']; - + $this->load->model('setting/setting'); - + $setting = $this->model_setting_setting->getSetting('payment_paypal'); - + $setting['payment_paypal_environment'] = $environment; $setting['payment_paypal_client_id'] = $client_id; $setting['payment_paypal_secret'] = $secret; @@ -142,82 +144,78 @@ public function index(): void { $setting['payment_paypal_total'] = 0; $setting['payment_paypal_geo_zone_id'] = 0; $setting['payment_paypal_sort_order'] = 0; + $setting['payment_paypal_setting']['general']['order_history_token'] = $order_history_token; + $setting['payment_paypal_setting']['general']['callback_token'] = $callback_token; $setting['payment_paypal_setting']['general']['webhook_token'] = $webhook_token; $setting['payment_paypal_setting']['general']['cron_token'] = $cron_token; - + $this->load->model('localisation/country'); - - $country = $this->model_localisation_country->getCountry((int)$this->config->get('config_country_id')); - + + $country = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); + $setting['payment_paypal_setting']['general']['country_code'] = $country['iso_code_2']; - + $currency_code = $this->config->get('config_currency'); $currency_value = $this->currency->getValue($this->config->get('config_currency')); - + if (!empty($config_setting['currency'][$currency_code]['status'])) { $setting['payment_paypal_setting']['general']['currency_code'] = $currency_code; $setting['payment_paypal_setting']['general']['currency_value'] = $currency_value; } - + if (!empty($config_setting['currency'][$currency_code]['card_status'])) { $setting['payment_paypal_setting']['general']['card_currency_code'] = $currency_code; $setting['payment_paypal_setting']['general']['card_currency_value'] = $currency_value; } - + $this->model_setting_setting->editSetting('payment_paypal', $setting); - - unset($this->session->data['authorization_code']); - unset($this->session->data['shared_id']); - unset($this->session->data['seller_nonce']); - - if (!$this->error) { - $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); - } } - + + if (!empty($this->request->get['merchantIdInPayPal']) && !$this->error) { + sleep(3); + + $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); + } + if (!$this->config->get('payment_paypal_client_id')) { $this->auth(); } else { $this->dashboard(); } } - - /** - * Auth - * - * @return void - */ - public function auth(): void { + + public function auth() { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); - + $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['partner_url'] = str_replace('&', '%26', $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); $data['callback_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/callback', 'user_token=' . $this->session->data['user_token'], true)); - $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + $data['connect_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/connect', 'user_token=' . $this->session->data['user_token'], true)); + $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -225,116 +223,108 @@ public function auth(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - - if (isset($this->session->data['environment'])) { - $data['environment'] = $this->session->data['environment']; - } else { - $data['environment'] = 'production'; - } - + + $data['authorization_type'] = 'automatic'; + $data['environment'] = 'production'; + $data['seller_nonce'] = $this->token(50); - - $data['configure_url'] = [ - 'production' => [ - 'ppcp' => 'https://www.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['production']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['production']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=PPCP,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'], + + $data['configure_url'] = array( + 'production' => array( + 'ppcp' => 'https://www.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['production']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['production']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=PPCP,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'], 'express_checkout' => 'https://www.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['production']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['production']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=EXPRESS_CHECKOUT,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'] - ], - 'sandbox' => [ - 'ppcp' => 'https://www.sandbox.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['sandbox']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['sandbox']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=PPCP,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'], + ), + 'sandbox' => array( + 'ppcp' => 'https://www.sandbox.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['sandbox']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['sandbox']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=PPCP,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'], 'express_checkout' => 'https://www.sandbox.paypal.com/bizsignup/partner/entry?partnerId=' . $data['setting']['partner']['sandbox']['partner_id'] . '&partnerClientId=' . $data['setting']['partner']['sandbox']['client_id'] . '&features=PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,VAULT,BILLING_AGREEMENT&product=EXPRESS_CHECKOUT,ADVANCED_VAULTING&capabilities=PAYPAL_WALLET_VAULTING_ADVANCED&integrationType=FO&returnToPartnerUrl=' . $data['partner_url'] . '&displayMode=minibrowser&sellerNonce=' . $data['seller_nonce'] - ] - ]; - + ) + ); + $data['text_checkout_express'] = sprintf($this->language->get('text_checkout_express'), $data['configure_url'][$data['environment']]['express_checkout']); $data['text_support'] = sprintf($this->language->get('text_support'), $this->request->server['HTTP_HOST']); - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); } - + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); $this->response->setOutput($this->load->view('extension/payment/paypal/auth', $data)); } - - /** - * Dashboard - * - * @return void - */ - public function dashboard(): void { + + public function dashboard() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - $this->load->model('setting/setting'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->setTitle($this->language->get('heading_title_main')); - $data['breadcrumbs'] = []; + $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); $data['href_button'] = $this->url->link('extension/payment/paypal/button', 'user_token=' . $this->session->data['user_token'], true); $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['sale_analytics_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getSaleAnalytics', 'user_token=' . $this->session->data['user_token'], true)); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -342,119 +332,114 @@ public function dashboard(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + if ($this->config->get('payment_paypal_status') != null) { $data['status'] = $this->config->get('payment_paypal_status'); } else { $data['status'] = 1; } - + if ($data['setting']['button']['product']['status'] || $data['setting']['button']['cart']['status'] || $data['setting']['button']['checkout']['status']) { $data['button_status'] = 1; } else { $data['button_status'] = 0; } - - if ($data['setting']['googlepay_button']['status']) { + + if ($data['setting']['googlepay_button']['product']['status'] || $data['setting']['googlepay_button']['cart']['status'] || $data['setting']['googlepay_button']['checkout']['status']) { $data['googlepay_button_status'] = 1; } else { $data['googlepay_button_status'] = 0; } - - if ($data['setting']['applepay_button']['status']) { + + if ($data['setting']['applepay_button']['product']['status'] || $data['setting']['applepay_button']['cart']['status'] || $data['setting']['applepay_button']['checkout']['status']) { $data['applepay_button_status'] = 1; } else { $data['applepay_button_status'] = 0; } - + if ($data['setting']['card']['status']) { $data['card_status'] = 1; } else { $data['card_status'] = 0; } - + if ($data['setting']['message']['home']['status'] || $data['setting']['message']['product']['status'] || $data['setting']['message']['cart']['status'] || $data['setting']['message']['checkout']['status']) { $data['message_status'] = 1; } else { $data['message_status'] = 0; } - + $paypal_sale_total = $this->model_extension_payment_paypal->getTotalSales(); - + $data['paypal_sale_total'] = $this->currency->format($paypal_sale_total, $this->config->get('config_currency')); - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); $this->response->setOutput($this->load->view('extension/payment/paypal/dashboard', $data)); } - - /** - * General - * - * @return void - */ - public function general(): void { + + public function general() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -462,15 +447,16 @@ public function general(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['disconnect_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/disconnect', 'user_token=' . $this->session->data['user_token'], true)); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -478,108 +464,103 @@ public function general(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + if ($this->config->get('payment_paypal_status') != null) { $data['status'] = $this->config->get('payment_paypal_status'); } else { $data['status'] = 1; } - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); $data['webhook_id'] = $this->config->get('payment_paypal_webhook_id'); $data['environment'] = $this->config->get('payment_paypal_environment'); - - $data['text_connect'] = sprintf($this->language->get('text_connect'), $data['client_id'], $data['secret'], $data['merchant_id'], $data['webhook_id'], $data['environment']); + + $data['text_connect'] = sprintf($this->language->get('text_connect'), $data['merchant_id'], $data['client_id'], $data['secret'], $data['webhook_id'], $data['environment']); $data['total'] = $this->config->get('payment_paypal_total'); - $data['geo_zone_id'] = (int)$this->config->get('payment_paypal_geo_zone_id'); + $data['geo_zone_id'] = $this->config->get('payment_paypal_geo_zone_id'); $data['sort_order'] = $this->config->get('payment_paypal_sort_order'); - + $this->load->model('localisation/geo_zone'); $data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones(); - + $this->load->model('localisation/country'); $data['countries'] = $this->model_localisation_country->getCountries(); - + $data['cron_url'] = $data['catalog'] . 'index.php?route=extension/payment/paypal&cron_token=' . $data['setting']['general']['cron_token']; - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/general', $data)); } - - /** - * Button - * - * @return void - */ - public function button(): void { + + public function button() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/paypal.js'); $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -587,14 +568,15 @@ public function button(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -602,14 +584,14 @@ public function button(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -618,124 +600,119 @@ public function button(): void { $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); - + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - + $data['currency_code'] = $data['setting']['general']['currency_code']; $data['currency_value'] = $data['setting']['general']['currency_value']; - + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; - - if ($data['client_id'] && $data['secret']) { + + if ($data['client_id'] && $data['secret']) { require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } } - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/button', $data)); } - - /** - * Googlepay Button - * - * @return void - */ - public function googlepay_button(): void { + + public function googlepay_button() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/paypal.js'); $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->addScript('https://pay.google.com/gp/p/js/pay.js'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -743,15 +720,15 @@ public function googlepay_button(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); - $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -759,14 +736,14 @@ public function googlepay_button(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -775,124 +752,119 @@ public function googlepay_button(): void { $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); - + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - + $data['currency_code'] = $data['setting']['general']['currency_code']; $data['currency_value'] = $data['setting']['general']['currency_value']; - + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; - - if ($data['client_id'] && $data['secret']) { + + if ($data['client_id'] && $data['secret']) { require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } } - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/googlepay_button', $data)); } - - /** - * Applepay Button - * - * @return void - */ - public function applepay_button(): void { + + public function applepay_button() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/paypal.js'); $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->addScript('https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -900,16 +872,17 @@ public function applepay_button(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['applepay_download_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/downloadAssociationFile', 'user_token=' . $this->session->data['user_token'], true)); $data['applepay_download_host_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/downloadHostAssociationFile', 'user_token=' . $this->session->data['user_token'], true)); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -917,14 +890,14 @@ public function applepay_button(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -933,124 +906,119 @@ public function applepay_button(): void { $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); - + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - + $data['currency_code'] = $data['setting']['general']['currency_code']; $data['currency_value'] = $data['setting']['general']['currency_value']; - + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; - - if ($data['client_id'] && $data['secret']) { + + if ($data['client_id'] && $data['secret']) { require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } } - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/applepay_button', $data)); } - - /** - * Card - * - * @return void - */ - public function card(): void { + + public function card() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/card.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/paypal.js'); $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -1058,14 +1026,15 @@ public function card(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -1073,14 +1042,14 @@ public function card(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -1089,123 +1058,119 @@ public function card(): void { $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); - + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - + $data['currency_code'] = $data['setting']['general']['currency_code']; $data['currency_value'] = $data['setting']['general']['currency_value']; - + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; - - if ($data['client_id'] && $data['secret']) { + + if ($data['client_id'] && $data['secret']) { require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } } - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/card', $data)); } - - /** - * Message - * - * @return void - */ - public function message(): void { + + public function message_configurator() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); - + $this->document->addScript('view/javascript/paypal/paypal.js'); $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); - + $this->document->addScript('https://www.paypalobjects.com/merchant-library/merchant-configurator.js'); + $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -1213,14 +1178,15 @@ public function message(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -1228,30 +1194,183 @@ public function message(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); $data['webhook_id'] = $this->config->get('payment_paypal_webhook_id'); $data['environment'] = $this->config->get('payment_paypal_environment'); + $data['partner_client_id'] = $data['setting']['partner'][$data['environment']]['client_id']; $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; - + $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); - + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - + $data['currency_code'] = $data['setting']['general']['currency_code']; $data['currency_value'] = $data['setting']['general']['currency_value']; - + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; + + if ($data['client_id'] && $data['secret']) { + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], + 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $data['client_token'] = $paypal->getClientToken(); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + } + + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); + + if (!empty($result['href'])) { + $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); + } else { + $data['text_version'] = ''; + } + + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); + + if (!$agree_status) { + $this->error['warning'] = $this->language->get('error_agree'); + } + + if (isset($this->error['warning'])) { + $data['error_warning'] = $this->error['warning']; + } else { + $data['error_warning'] = ''; + } + + $data['header'] = $this->load->controller('common/header'); + $data['column_left'] = $this->load->controller('common/column_left'); + $data['footer'] = $this->load->controller('common/footer'); + + $this->response->setOutput($this->load->view('extension/payment/paypal/message_configurator', $data)); + } + + public function message_setting() { + if (!$this->config->get('payment_paypal_client_id')) { + $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); + } + + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); + $this->document->addStyle('view/stylesheet/paypal/bootstrap-switch.css'); + + $this->document->addScript('view/javascript/paypal/paypal.js'); + $this->document->addScript('view/javascript/paypal/bootstrap-switch.js'); + + $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_home'), + 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) + ); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_extensions'), + 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) + ); + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('heading_title_main'), + 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) + ); + + // Action + $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); + $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); + $data['href_button'] = $this->url->link('extension/payment/paypal/button', 'user_token=' . $this->session->data['user_token'], true); + $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); + $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); + $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); + $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); + $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); + + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); + $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); + $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); + + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { + $data['server'] = HTTPS_SERVER; + $data['catalog'] = HTTPS_CATALOG; + } else { + $data['server'] = HTTP_SERVER; + $data['catalog'] = HTTP_CATALOG; + } + + $_config = new Config(); + $_config->load('paypal'); + + $data['setting'] = $_config->get('paypal_setting'); + + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); + + $data['client_id'] = $this->config->get('payment_paypal_client_id'); + $data['secret'] = $this->config->get('payment_paypal_secret'); + $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); + $data['webhook_id'] = $this->config->get('payment_paypal_webhook_id'); + $data['environment'] = $this->config->get('payment_paypal_environment'); + $data['partner_client_id'] = $data['setting']['partner'][$data['environment']]['client_id']; + $data['partner_attribution_id'] = $data['setting']['partner'][$data['environment']]['partner_attribution_id']; + + $country = $this->model_extension_payment_paypal->getCountryByCode($data['setting']['general']['country_code']); + + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; + + $data['currency_code'] = $data['setting']['general']['currency_code']; + $data['currency_value'] = $data['setting']['general']['currency_value']; + + $data['decimal_place'] = $data['setting']['currency'][$data['currency_code']]['decimal_place']; + if ($country['iso_code_2'] == 'GB') { $data['text_message_alert'] = $this->language->get('text_message_alert_uk'); $data['text_message_footnote'] = $this->language->get('text_message_footnote_uk'); @@ -1259,112 +1378,107 @@ public function message(): void { $data['text_message_alert'] = $this->language->get('text_message_alert_us'); $data['text_message_footnote'] = $this->language->get('text_message_footnote_us'); } - - if ($data['client_id'] && $data['secret']) { + + if ($data['client_id'] && $data['secret']) { require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + $paypal_info = array( + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['setting']['partner'][$data['environment']]['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } } - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - - $this->response->setOutput($this->load->view('extension/payment/paypal/message', $data)); + + $this->response->setOutput($this->load->view('extension/payment/paypal/message_setting', $data)); } - - /** - * Order Status - * - * @return void - */ - public function order_status(): void { + + public function order_status() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -1372,14 +1486,15 @@ public function order_status(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -1387,20 +1502,20 @@ public function order_status(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $this->load->model('localisation/order_status'); $data['order_statuses'] = $this->model_localisation_order_status->getOrderStatuses(); - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { @@ -1408,59 +1523,54 @@ public function order_status(): void { } $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; - } - + } + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/order_status', $data)); } - - /** - * Contact - * - * @return void - */ - public function contact(): void { + + public function contact() { if (!$this->config->get('payment_paypal_client_id')) { $this->response->redirect($this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true)); } - + $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $this->document->addStyle('view/stylesheet/paypal/paypal.css'); $this->document->setTitle($this->language->get('heading_title_main')); + + $data['breadcrumbs'] = array(); - $data['breadcrumbs'] = []; - - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_extensions'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title_main'), 'href' => $this->url->link('extension/payment/paypal', 'user_token=' . $this->session->data['user_token'], true) - ]; - + ); + // Action $data['href_dashboard'] = $this->url->link('extension/payment/paypal/dashboard', 'user_token=' . $this->session->data['user_token'], true); $data['href_general'] = $this->url->link('extension/payment/paypal/general', 'user_token=' . $this->session->data['user_token'], true); @@ -1468,15 +1578,16 @@ public function contact(): void { $data['href_googlepay_button'] = $this->url->link('extension/payment/paypal/googlepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_applepay_button'] = $this->url->link('extension/payment/paypal/applepay_button', 'user_token=' . $this->session->data['user_token'], true); $data['href_card'] = $this->url->link('extension/payment/paypal/card', 'user_token=' . $this->session->data['user_token'], true); - $data['href_message'] = $this->url->link('extension/payment/paypal/message', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_configurator'] = $this->url->link('extension/payment/paypal/message_configurator', 'user_token=' . $this->session->data['user_token'], true); + $data['href_message_setting'] = $this->url->link('extension/payment/paypal/message_setting', 'user_token=' . $this->session->data['user_token'], true); $data['href_order_status'] = $this->url->link('extension/payment/paypal/order_status', 'user_token=' . $this->session->data['user_token'], true); $data['href_contact'] = $this->url->link('extension/payment/paypal/contact', 'user_token=' . $this->session->data['user_token'], true); - + $data['action'] = $this->url->link('extension/payment/paypal/save', 'user_token=' . $this->session->data['user_token'], true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true); $data['contact_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/sendContact', 'user_token=' . $this->session->data['user_token'], true)); $data['agree_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/agree', 'user_token=' . $this->session->data['user_token'], true)); - + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { $data['server'] = HTTPS_SERVER; $data['catalog'] = HTTPS_CATALOG; @@ -1484,133 +1595,261 @@ public function contact(): void { $data['server'] = HTTP_SERVER; $data['catalog'] = HTTP_CATALOG; } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $data['setting'] = $_config->get('paypal_setting'); - + $data['setting'] = array_replace_recursive((array)$data['setting'], (array)$this->config->get('payment_paypal_setting')); - + $this->load->model('localisation/country'); $data['countries'] = $this->model_localisation_country->getCountries(); - + $result = $this->model_extension_payment_paypal->checkVersion(VERSION, $data['setting']['version']); - + if (!empty($result['href'])) { $data['text_version'] = sprintf($this->language->get('text_version'), $result['href']); } else { $data['text_version'] = ''; } - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if (!$agree_status) { $this->error['warning'] = $this->language->get('error_agree'); - } - + } + if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } - + $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); - + $this->response->setOutput($this->load->view('extension/payment/paypal/contact', $data)); } - - /** - * Save - * - * @return void - */ - public function save(): void { + + public function save() { $this->load->language('extension/payment/paypal'); - + $this->load->model('setting/setting'); - + if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { $setting = $this->model_setting_setting->getSetting('payment_paypal'); - + $setting = array_replace_recursive($setting, $this->request->post); - + $this->model_setting_setting->editSetting('payment_paypal', $setting); - + $data['success'] = $this->language->get('success_save'); } - + $data['error'] = $this->error; - + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function connect() { + $this->load->language('extension/payment/paypal'); + + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { + $server = HTTPS_SERVER; + $catalog = HTTPS_CATALOG; + } else { + $server = HTTP_SERVER; + $catalog = HTTP_CATALOG; + } + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + if (!empty($this->request->post['environment']) && !empty($this->request->post['client_id']) && !empty($this->request->post['client_secret']) && !empty($this->request->post['merchant_id'])) { + $this->load->model('extension/payment/paypal'); + + $environment = $this->request->post['environment']; + $client_id = $this->request->post['client_id']; + $secret = $this->request->post['client_secret']; + $merchant_id = $this->request->post['merchant_id']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $config_setting['partner'][$environment]['partner_id'], + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $config_setting['partner'][$environment]['partner_attribution_id'] + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $result = $paypal->setAccessToken($token_info); + + if ($result) { + $order_history_token = sha1(uniqid(mt_rand(), 1)); + $callback_token = sha1(uniqid(mt_rand(), 1)); + $webhook_token = sha1(uniqid(mt_rand(), 1)); + $cron_token = sha1(uniqid(mt_rand(), 1)); + + $webhook_info = array( + 'url' => $catalog . 'index.php?route=extension/payment/paypal&webhook_token=' . $webhook_token, + 'event_types' => array( + array('name' => 'PAYMENT.AUTHORIZATION.CREATED'), + array('name' => 'PAYMENT.AUTHORIZATION.VOIDED'), + array('name' => 'PAYMENT.CAPTURE.COMPLETED'), + array('name' => 'PAYMENT.CAPTURE.DENIED'), + array('name' => 'PAYMENT.CAPTURE.PENDING'), + array('name' => 'PAYMENT.CAPTURE.REFUNDED'), + array('name' => 'PAYMENT.CAPTURE.REVERSED'), + array('name' => 'CHECKOUT.ORDER.COMPLETED'), + array('name' => 'VAULT.PAYMENT-TOKEN.CREATED') + ) + ); + + $result = $paypal->createWebhook($webhook_info); + + $webhook_id = ''; + + if (isset($result['id'])) { + $webhook_id = $result['id']; + } + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (!$this->error) { + $this->load->model('setting/setting'); + + $setting = $this->model_setting_setting->getSetting('payment_paypal'); + + $setting['payment_paypal_environment'] = $environment; + $setting['payment_paypal_client_id'] = $client_id; + $setting['payment_paypal_secret'] = $secret; + $setting['payment_paypal_merchant_id'] = $merchant_id; + $setting['payment_paypal_webhook_id'] = $webhook_id; + $setting['payment_paypal_status'] = 1; + $setting['payment_paypal_total'] = 0; + $setting['payment_paypal_geo_zone_id'] = 0; + $setting['payment_paypal_sort_order'] = 0; + $setting['payment_paypal_setting']['general']['order_history_token'] = $order_history_token; + $setting['payment_paypal_setting']['general']['callback_token'] = $callback_token; + $setting['payment_paypal_setting']['general']['webhook_token'] = $webhook_token; + $setting['payment_paypal_setting']['general']['cron_token'] = $cron_token; + + $this->load->model('localisation/country'); + + $country = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); + + $setting['payment_paypal_setting']['general']['country_code'] = $country['iso_code_2']; + + $currency_code = $this->config->get('config_currency'); + $currency_value = $this->currency->getValue($this->config->get('config_currency')); + + if (!empty($config_setting['currency'][$currency_code]['status'])) { + $setting['payment_paypal_setting']['general']['currency_code'] = $currency_code; + $setting['payment_paypal_setting']['general']['currency_value'] = $currency_value; + } + + if (!empty($config_setting['currency'][$currency_code]['card_status'])) { + $setting['payment_paypal_setting']['general']['card_currency_code'] = $currency_code; + $setting['payment_paypal_setting']['general']['card_currency_value'] = $currency_value; + } + + $this->model_setting_setting->editSetting('payment_paypal', $setting); + } + } else { + $this->error['warning'] = $this->language->get('error_connect'); + } + } else { + $this->error['warning'] = $this->language->get('error_connect'); + } + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($data)); } - - /** - * Disconnect - * - * @return void - */ - public function disconnect(): void { + + public function disconnect() { $this->load->model('setting/setting'); - + $setting = $this->model_setting_setting->getSetting('payment_paypal'); - + $setting['payment_paypal_client_id'] = ''; $setting['payment_paypal_secret'] = ''; $setting['payment_paypal_merchant_id'] = ''; $setting['payment_paypal_webhook_id'] = ''; - + $this->model_setting_setting->editSetting('payment_paypal', $setting); - + $data['error'] = $this->error; - + $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($data)); } - - /** - * Callback - * - * @return void - */ - public function callback(): void { + + public function callback() { if (isset($this->request->post['environment']) && isset($this->request->post['authorization_code']) && isset($this->request->post['shared_id']) && isset($this->request->post['seller_nonce'])) { - $this->session->data['environment'] = $this->request->post['environment']; - $this->session->data['authorization_code'] = $this->request->post['authorization_code']; - $this->session->data['shared_id'] = $this->request->post['shared_id']; - $this->session->data['seller_nonce'] = $this->request->post['seller_nonce']; - } - + $cache_data['environment'] = $this->request->post['environment']; + $cache_data['authorization_code'] = $this->request->post['authorization_code']; + $cache_data['shared_id'] = $this->request->post['shared_id']; + $cache_data['seller_nonce'] = $this->request->post['seller_nonce']; + + $this->cache->set('paypal', $cache_data, 30); + } + $data['error'] = $this->error; - + $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($data)); - } - - /** - * Get Sale Analytics - * - * @return void - */ - public function getSaleAnalytics(): void { + } + + public function getSaleAnalytics() { $this->load->language('extension/payment/paypal'); - $json = []; + $data = array(); $this->load->model('extension/payment/paypal'); - $json['all_sale'] = []; - $json['paypal_sale'] = []; - $json['xaxis'] = []; - - $json['all_sale']['label'] = $this->language->get('text_all_sales'); - $json['paypal_sale']['label'] = $this->language->get('text_paypal_sales'); - $json['all_sale']['data'] = []; - $json['paypal_sale']['data'] = []; + $data['all_sale'] = array(); + $data['paypal_sale'] = array(); + $data['xaxis'] = array(); + + $data['all_sale']['label'] = $this->language->get('text_all_sales'); + $data['paypal_sale']['label'] = $this->language->get('text_paypal_sales'); + $data['all_sale']['data'] = array(); + $data['paypal_sale']['data'] = array(); if (isset($this->request->get['range'])) { $range = $this->request->get['range']; @@ -1624,20 +1863,21 @@ public function getSaleAnalytics(): void { $results = $this->model_extension_payment_paypal->getTotalSalesByDay(); foreach ($results as $key => $value) { - $json['all_sale']['data'][] = [$key, $value['total']]; - $json['paypal_sale']['data'][] = [$key, $value['paypal_total']]; + $data['all_sale']['data'][] = array($key, $value['total']); + $data['paypal_sale']['data'][] = array($key, $value['paypal_total']); } for ($i = 0; $i < 24; $i++) { - $json['xaxis'][] = [$i, $i]; + $data['xaxis'][] = array($i, $i); } + break; case 'week': $results = $this->model_extension_payment_paypal->getTotalSalesByWeek(); foreach ($results as $key => $value) { - $json['all_sale']['data'][] = [$key, $value['total']]; - $json['paypal_sale']['data'][] = [$key, $value['paypal_total']]; + $data['all_sale']['data'][] = array($key, $value['total']); + $data['paypal_sale']['data'][] = array($key, $value['paypal_total']); } $date_start = strtotime('-' . date('w') . ' days'); @@ -1645,805 +1885,1394 @@ public function getSaleAnalytics(): void { for ($i = 0; $i < 7; $i++) { $date = date('Y-m-d', $date_start + ($i * 86400)); - $json['xaxis'][] = [date('w', strtotime($date)), date('D', strtotime($date))]; + $data['xaxis'][] = array(date('w', strtotime($date)), date('D', strtotime($date))); } + break; case 'month': $results = $this->model_extension_payment_paypal->getTotalSalesByMonth(); foreach ($results as $key => $value) { - $json['all_sale']['data'][] = [$key, $value['total']]; - $json['paypal_sale']['data'][] = [$key, $value['paypal_total']]; + $data['all_sale']['data'][] = array($key, $value['total']); + $data['paypal_sale']['data'][] = array($key, $value['paypal_total']); } for ($i = 1; $i <= date('t'); $i++) { $date = date('Y') . '-' . date('m') . '-' . $i; - $json['xaxis'][] = [date('j', strtotime($date)), date('d', strtotime($date))]; + + $data['xaxis'][] = array(date('j', strtotime($date)), date('d', strtotime($date))); } + break; case 'year': $results = $this->model_extension_payment_paypal->getTotalSalesByYear(); foreach ($results as $key => $value) { - $json['all_sale']['data'][] = [$key, $value['total']]; - $json['paypal_sale']['data'][] = [$key, $value['paypal_total']]; + $data['all_sale']['data'][] = array($key, $value['total']); + $data['paypal_sale']['data'][] = array($key, $value['paypal_total']); } for ($i = 1; $i <= 12; $i++) { - $json['xaxis'][] = [$i, date('M', mktime(0, 0, 0, $i))]; + $data['xaxis'][] = array($i, date('M', mktime(0, 0, 0, $i))); } + break; } $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Download Association File - * - * @return void - */ - public function downloadAssociationFile(): void { + + public function downloadAssociationFile() { $environment = $this->config->get('payment_paypal_environment'); - + if ($environment == 'production') { - $file = 'https://www.paypalobjects.com/.well-known/apple-developer-merchantid-domain-association'; - - $file_headers = @get_headers($file); - - if (str_contains($file_headers[0], '404')) { - $file = 'https://www.paypalobjects.com/.well-known/apple-developer-merchantid-domain-association.txt'; - } + $file = 'https://developer.paypal.com/downloads/apple-pay/production/domain-association-file-live'; } else { $file = 'https://www.paypalobjects.com/sandbox/apple-developer-merchantid-domain-association'; } - + header('Content-Description: File Transfer'); header('Content-Type: text/plain'); header('Content-Disposition: attachment; filename="' . basename($file, '.txt') . '"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); - + readfile($file); } - - /** - * Download Host Associate File - * - * @return void - */ - public function downloadHostAssociationFile(): void { + + public function downloadHostAssociationFile() { $this->load->language('extension/payment/paypal'); - - $json = []; - + $environment = $this->config->get('payment_paypal_environment'); - + if ($environment == 'production') { - $file = 'https://www.paypalobjects.com/.well-known/apple-developer-merchantid-domain-association'; - - $file_headers = @get_headers($file); - - if (str_contains($file_headers[0], '404')) { - $file = 'https://www.paypalobjects.com/.well-known/apple-developer-merchantid-domain-association.txt'; - } + $file = 'https://developer.paypal.com/downloads/apple-pay/production/domain-association-file-live'; } else { $file = 'https://www.paypalobjects.com/sandbox/apple-developer-merchantid-domain-association'; } - + $content = file_get_contents($file); - + if ($content) { $dir = str_replace('admin/', '.well-known/', DIR_APPLICATION); - + if (!file_exists($dir)) { - mkdir($dir, 0o777, true); + mkdir($dir, 0777, true); } - + if (file_exists($dir)) { $fh = fopen($dir . basename($file, '.txt'), 'w'); fwrite($fh, $content); fclose($fh); } - + $data['success'] = $this->language->get('success_download_host'); } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Send Contact - * - * @return void - */ - public function sendContact(): void { + + public function sendContact() { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + if (isset($this->request->post['payment_paypal_setting']['contact'])) { $this->model_extension_payment_paypal->sendContact($this->request->post['payment_paypal_setting']['contact']); - + $data['success'] = $this->language->get('success_send'); } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Agree - * - * @return void - */ - public function agree(): void { + + public function agree() { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + $this->model_extension_payment_paypal->setAgreeStatus(); - - $json['success'] = $this->language->get('success_agree'); - - $json['error'] = $this->error; - + + $data['success'] = $this->language->get('success_agree'); + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Install - * - * @return void - */ - public function install(): void { + + public function install() { $this->load->model('extension/payment/paypal'); - + $this->model_extension_payment_paypal->install(); - + $this->load->model('setting/event'); - + $this->model_setting_event->deleteEventByCode('paypal_order_info'); $this->model_setting_event->deleteEventByCode('paypal_header'); $this->model_setting_event->deleteEventByCode('paypal_extension_get_extensions'); $this->model_setting_event->deleteEventByCode('paypal_order_delete_order'); - + $this->model_setting_event->deleteEventByCode('paypal_customer_delete_customer'); + $this->model_setting_event->addEvent('paypal_order_info', 'admin/view/sale/order_info/before', 'extension/payment/paypal/order_info_before'); $this->model_setting_event->addEvent('paypal_header', 'catalog/controller/common/header/before', 'extension/payment/paypal/header_before'); $this->model_setting_event->addEvent('paypal_extension_get_extensions', 'catalog/model/setting/extension/getExtensions/after', 'extension/payment/paypal/extension_get_extensions_after'); $this->model_setting_event->addEvent('paypal_order_delete_order', 'catalog/model/checkout/order/deleteOrder/before', 'extension/payment/paypal/order_delete_order_before'); - - $_config = new \Config(); + $this->model_setting_event->addEvent('paypal_customer_delete_customer', 'admin/model/customer/customer/deleteCustomer/before', 'extension/payment/paypal/customer_delete_customer_before'); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting['paypal_version'] = $config_setting['version']; - + $this->load->model('setting/setting'); - + $this->model_setting_setting->editSetting('paypal_version', $setting); } + + public function uninstall() { + $this->load->model('extension/payment/paypal'); + + $this->model_extension_payment_paypal->uninstall(); + + $this->load->model('setting/event'); + + $this->model_setting_event->deleteEventByCode('paypal_order_info'); + $this->model_setting_event->deleteEventByCode('paypal_header'); + $this->model_setting_event->deleteEventByCode('paypal_extension_get_extensions'); + $this->model_setting_event->deleteEventByCode('paypal_order_delete_order'); + $this->model_setting_event->deleteEventByCode('paypal_customer_delete_customer'); + + $this->load->model('setting/setting'); + + $this->model_setting_setting->deleteSetting('paypal_version'); + } + + public function update() { + $this->load->model('extension/payment/paypal'); + + $this->model_extension_payment_paypal->update(); + + $this->load->model('setting/event'); + + $this->model_setting_event->deleteEventByCode('paypal_order_info'); + $this->model_setting_event->deleteEventByCode('paypal_header'); + $this->model_setting_event->deleteEventByCode('paypal_extension_get_extensions'); + $this->model_setting_event->deleteEventByCode('paypal_order_delete_order'); + $this->model_setting_event->deleteEventByCode('paypal_customer_delete_customer'); + + $this->model_setting_event->addEvent('paypal_order_info', 'admin/view/sale/order_info/before', 'extension/payment/paypal/order_info_before'); + $this->model_setting_event->addEvent('paypal_header', 'catalog/controller/common/header/before', 'extension/payment/paypal/header_before'); + $this->model_setting_event->addEvent('paypal_extension_get_extensions', 'catalog/model/setting/extension/getExtensions/after', 'extension/payment/paypal/extension_get_extensions_after'); + $this->model_setting_event->addEvent('paypal_order_delete_order', 'catalog/model/checkout/order/deleteOrder/before', 'extension/payment/paypal/order_delete_order_before'); + $this->model_setting_event->addEvent('paypal_customer_delete_customer', 'admin/model/customer/customer/deleteCustomer/before', 'extension/payment/paypal/customer_delete_customer_before'); + + if ($this->config->get('paypal_version') < '3.1.0') { + $this->load->model('setting/setting'); + + $setting = $this->model_setting_setting->getSetting('payment_paypal'); + + $setting['payment_paypal_setting']['general']['order_history_token'] = sha1(uniqid(mt_rand(), 1)); + + $this->model_setting_setting->editSetting('payment_paypal', $setting); + } + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting['paypal_version'] = $config_setting['version']; + + $this->load->model('setting/setting'); + + $this->model_setting_setting->editSetting('paypal_version', $setting); + } + + public function customer_delete_customer_before($route, &$data) { + $this->load->model('extension/payment/paypal'); + + $customer_id = $data[0]; - /** - * Order Info Before - * - * @param string $route - * @param array $data - * - * @return void - */ - public function order_info_before(&$route, &$data): void { + $this->model_extension_payment_paypal->deletePayPalCustomerTokens($customer_id); + } + + public function order_info_before($route, &$data) { if ($this->config->get('payment_paypal_status') && !empty($this->request->get['order_id'])) { $this->load->language('extension/payment/paypal'); - $this->load->model('extension/payment/paypal'); - - $data['order_id'] = (int)$this->request->get['order_id']; - - $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($data['order_id']); - - if ($paypal_order_info) { - $data['transaction_id'] = $paypal_order_info['transaction_id']; - $data['transaction_status'] = $paypal_order_info['transaction_status']; - - if ($paypal_order_info['environment'] == 'production') { - $data['transaction_url'] = 'https://www.paypal.com/activity/payment/' . $data['transaction_id']; - } else { - $data['transaction_url'] = 'https://www.sandbox.paypal.com/activity/payment/' . $data['transaction_id']; - } - - $data['info_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getPaymentInfo', 'user_token=' . $this->session->data['user_token'] . '&order_id=' . $data['order_id'], true)); - $data['capture_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/capturePayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['reauthorize_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/reauthorizePayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['void_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/voidPayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['refund_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/refundPayment', 'user_token=' . $this->session->data['user_token'], true)); - - $data['tabs'][] = [ + $content = $this->getPaymentDetails((int)$this->request->get['order_id']); + + if ($content) { + $data['tabs'][] = array( 'code' => 'paypal', 'title' => $this->language->get('heading_title_main'), - 'content' => $this->load->view('extension/payment/paypal/order', $data) - ]; - } + 'content' => $content + ); + } } } - - /** - * Get Payment Info - * - * @return void - */ - public function getPaymentInfo(): void { + + public function getPaymentInfo() { $content = ''; - - if ($this->config->get('payment_paypal_status') && !empty($this->request->get['order_id'])) { + + if (!empty($this->request->get['order_id'])) { $this->load->language('extension/payment/paypal'); - - $this->load->model('extension/payment/paypal'); - - $data['order_id'] = (int)$this->request->get['order_id']; - - $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($data['order_id']); - - if ($paypal_order_info) { - $data['transaction_id'] = $paypal_order_info['transaction_id']; - $data['transaction_status'] = $paypal_order_info['transaction_status']; - - if ($paypal_order_info['environment'] == 'production') { - $data['transaction_url'] = 'https://www.paypal.com/activity/payment/' . $data['transaction_id']; - } else { - $data['transaction_url'] = 'https://www.sandbox.paypal.com/activity/payment/' . $data['transaction_id']; - } - - $data['info_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getPaymentInfo', 'user_token=' . $this->session->data['user_token'] . '&order_id=' . $data['order_id'], true)); - $data['capture_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/capturePayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['reauthorize_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/reauthorizePayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['void_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/voidPayment', 'user_token=' . $this->session->data['user_token'], true)); - $data['refund_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/refundPayment', 'user_token=' . $this->session->data['user_token'], true)); - - $content = $this->load->view('extension/payment/paypal/order', $data); - } + + $content = $this->getPaymentDetails((int)$this->request->get['order_id']); } - + $this->response->setOutput($content); } + + private function getPaymentDetails($order_id) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + $this->load->model('sale/order'); + + $order_info = $this->model_sale_order->getOrder($order_id); + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); + + if ($order_info && $paypal_order_info) { + $data['order_id'] = $order_id; + $data['paypal_order_id'] = $paypal_order_info['paypal_order_id']; + $data['transaction_id'] = $paypal_order_info['transaction_id']; + $data['transaction_status'] = $paypal_order_info['transaction_status']; + + if ($paypal_order_info['environment'] == 'production') { + $data['transaction_url'] = 'https://www.paypal.com/activity/payment/' . $data['transaction_id']; + } else { + $data['transaction_url'] = 'https://www.sandbox.paypal.com/activity/payment/' . $data['transaction_id']; + } + + $data['tracking_number'] = $paypal_order_info['tracking_number']; + $data['carrier_name'] = $paypal_order_info['carrier_name']; + + $data['info_payment_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getPaymentInfo', 'user_token=' . $this->session->data['user_token'] . '&order_id=' . $data['order_id'], true)); + $data['capture_payment_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/capturePayment', 'user_token=' . $this->session->data['user_token'], true)); + $data['reauthorize_payment_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/reauthorizePayment', 'user_token=' . $this->session->data['user_token'], true)); + $data['void_payment_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/voidPayment', 'user_token=' . $this->session->data['user_token'], true)); + $data['refund_payment_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/refundPayment', 'user_token=' . $this->session->data['user_token'], true)); + $data['autocomplete_carrier_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/autocompleteCarrier', 'user_token=' . $this->session->data['user_token'], true)); + $data['create_tracker_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/createTracker', 'user_token=' . $this->session->data['user_token'], true)); + $data['cancel_tracker_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/cancelTracker', 'user_token=' . $this->session->data['user_token'], true)); + + $data['country_code'] = ''; + + $country_id = $this->config->get('config_country_id'); + + if ($order_info['shipping_country_id']) { + $country_id = $order_info['shipping_country_id']; + } - /** - * Capture Payment - * - * @return void - */ - public function capturePayment(): void { - if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && !empty($this->request->post['transaction_id'])) { - $this->load->language('extension/payment/paypal'); - - $json = []; - - $this->load->model('extension/payment/paypal'); - - $order_id = (int)$this->request->post['order_id']; - $transaction_id = $this->request->post['transaction_id']; - - $_config = new \Config(); + if ($country_id) { + $this->load->model('localisation/country'); + + $country_info = $this->model_localisation_country->getCountry($order_info['shipping_country_id']); + + if ($country_info) { + $data['country_code'] = $country_info['iso_code_3']; + } + } + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $vault_status = $setting['general']['vault_status']; $transaction_method = $setting['general']['transaction_method']; - + + $decimal_place = $setting['currency'][$paypal_order_info['currency_code']]['decimal_place']; + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - - $result = $paypal->setPaymentCapture($transaction_id); - + + $paypal_order_info = $paypal->getOrder($data['paypal_order_id']); + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - - if (isset($result['id']) && isset($result['status']) && !$this->error) { - $transaction_id = $result['id']; - $transaction_status = 'completed'; - - $paypal_order_data = [ - 'order_id' => $order_id, - 'transaction_id' => $transaction_id, - 'transaction_status' => $transaction_status - ]; + + $authorization_amount = 0; + $capture_amount = 0; + $refund_amount = 0; + + if (isset($paypal_order_info['purchase_units'][0]['payments']) && !$this->error) { + $payments = $paypal_order_info['purchase_units'][0]['payments']; + + $order_status_id = 0; + $transaction_id = $data['transaction_id']; + $transaction_status = $data['transaction_status']; + + if (!empty($payments['authorizations'])) { + foreach ($payments['authorizations'] as $authorization) { + $transaction_id = $authorization['id']; + + if (($authorization['status'] == 'CREATED') || ($authorization['status'] == 'PENDING')) { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'created'; + } + + if ($authorization['status'] == 'CAPTURED') { + $order_status_id = $setting['order_status']['completed']['id']; + $transaction_status = 'completed'; + } + + if ($authorization['status'] == 'PARTIALLY_CAPTURED') { + $order_status_id = $setting['order_status']['partially_captured']['id']; + $transaction_status = 'partially_captured'; + } + + if ($authorization['status'] == 'VOIDED') { + $order_status_id = $setting['order_status']['voided']['id']; + $transaction_status = 'voided'; + } + + if (($authorization['status'] == 'CREATED') || ($authorization['status'] == 'CAPTURED') || ($authorization['status'] == 'PARTIALLY_CAPTURED') || ($authorization['status'] == 'PENDING')) { + $authorization_amount = $authorization['amount']['value']; + } + } + } + + if (!empty($payments['captures'])) { + foreach ($payments['captures'] as $capture) { + if (($capture['status'] == 'COMPLETED') && ($transaction_status == 'completed')) { + $order_status_id = $setting['order_status']['completed']['id']; + $transaction_id = $capture['id']; + $transaction_status = 'completed'; + } + + if ($capture['status'] == 'PARTIALLY_REFUNDED') { + $order_status_id = $setting['order_status']['partially_refunded']['id']; + $transaction_status = 'partially_refunded'; + } + + if ($capture['status'] == 'REFUNDED') { + $order_status_id = $setting['order_status']['refunded']['id']; + $transaction_status = 'refunded'; + } + + if (($capture['status'] == 'COMPLETED') || ($capture['status'] == 'PARTIALLY_REFUNDED') || ($capture['status'] == 'REFUNDED')) { + $capture_amount += $capture['amount']['value']; + } + } + } + + if (!empty($payments['refunds'])) { + foreach ($payments['refunds'] as $refund) { + if ($refund['status'] == 'COMPLETED') { + $refund_amount += $refund['amount']['value']; + } + } + } + + if ($order_status_id && ($order_info['order_status_id'] != $order_status_id)) { + $this->model_extension_payment_paypal->addOrderHistory($setting['general']['order_history_token'], $order_id, $order_status_id); + } + + $paypal_order_data = array(); + + $paypal_order_data['order_id'] = $order_id; + $paypal_order_data['transaction_status'] = $transaction_status; + $paypal_order_data['transaction_id'] = $transaction_id; $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); - - $json['success'] = $this->language->get('success_capture_payment'); + + $data['transaction_id'] = $transaction_id; + $data['transaction_status'] = $transaction_status; } - } - - $json['error'] = $this->error; - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + + $data['capture_amount'] = number_format($authorization_amount - $capture_amount, $decimal_place, '.', ''); + $data['reauthorize_amount'] = number_format($authorization_amount, $decimal_place, '.', ''); + $data['refund_amount'] = number_format($capture_amount - $refund_amount, $decimal_place, '.', ''); + + return $this->load->view('extension/payment/paypal/order', $data); + } + + return ''; } - - /** - * Reauthorize Payment - * - * @return void - */ - public function reauthorizePayment(): void { - if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && !empty($this->request->post['transaction_id'])) { + + public function capturePayment() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id'])) { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + $this->load->model('sale/order'); + $order_id = (int)$this->request->post['order_id']; - $transaction_id = $this->request->post['transaction_id']; - - $_config = new \Config(); - $_config->load('paypal'); - - $config_setting = $_config->get('paypal_setting'); - - $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - - $client_id = $this->config->get('payment_paypal_client_id'); - $secret = $this->config->get('payment_paypal_secret'); - $environment = $this->config->get('payment_paypal_environment'); - $partner_id = $setting['partner'][$environment]['partner_id']; - $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; - $transaction_method = $setting['general']['transaction_method']; - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, - 'partner_attribution_id' => $partner_attribution_id - ]; - - $paypal = new PayPal($paypal_info); - - $token_info = [ - 'grant_type' => 'client_credentials' - ]; - - $paypal->setAccessToken($token_info); - - $result = $paypal->setPaymentReauthorize($transaction_id); - - if ($paypal->hasErrors()) { - $error_messages = []; - - $errors = $paypal->getErrors(); - - foreach ($errors as $error) { - if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { - $error['message'] = $this->language->get('error_timeout'); + $capture_amount = (float)$this->request->post['capture_amount']; + + if (!empty($this->request->post['final_capture'])) { + $final_capture = true; + } else { + $final_capture = false; + } + + $order_info = $this->model_sale_order->getOrder($order_id); + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); + + if ($order_info && $paypal_order_info) { + $transaction_id = $paypal_order_info['transaction_id']; + $currency_code = $paypal_order_info['currency_code']; + $order_status_id = 0; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + $decimal_place = $setting['currency'][$paypal_order_info['currency_code']]['decimal_place']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $transaction_info = array( + 'amount' => array( + 'value' => number_format($capture_amount, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ), + 'final_capture' => $final_capture + ); + + $result = $paypal->setPaymentCapture($transaction_id, $transaction_info); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); } - - if (isset($error['details'][0]['description'])) { - $error_messages[] = $error['details'][0]['description']; - } elseif (isset($error['message'])) { - $error_messages[] = $error['message']; + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($result['id']) && isset($result['status']) && !$this->error) { + $result = $paypal->getPaymentAuthorize($transaction_id); + + if (!empty($result['status'] == 'CAPTURED')) { + $order_status_id = $setting['order_status']['completed']['id']; + $transaction_status = 'completed'; + $transaction_id = $result['id']; + } elseif (!empty($result['status'] == 'PARTIALLY_CAPTURED')) { + $order_status_id = $setting['order_status']['partially_captured']['id']; + $transaction_status = 'partially_captured'; } - - $this->model_extension_payment_paypal->log($error, $error['message']); + + if ($order_status_id && ($order_info['order_status_id'] != $order_status_id)) { + $this->model_extension_payment_paypal->addOrderHistory($setting['general']['order_history_token'], $order_id, $order_status_id); + } + + $paypal_order_data = array(); + + $paypal_order_data['order_id'] = $order_id; + $paypal_order_data['transaction_id'] = $transaction_id; + $paypal_order_data['transaction_status'] = $transaction_status; + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $data['success'] = $this->language->get('success_capture_payment'); } - - $this->error['warning'] = implode(' ', $error_messages); - } - - if (isset($result['id']) && isset($result['status']) && !$this->error) { - $transaction_id = $result['id']; - $transaction_status = 'created'; - - $this->model_extension_payment_paypal->deletePayPalOrder($order_id); - - $paypal_order_data = [ - 'order_id' => $order_id, - 'transaction_id' => $transaction_id, - 'transaction_status' => $transaction_status - ]; - - $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); - - $json['success'] = $this->language->get('success_reauthorize_payment'); } } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Void Payment - * - * @return void - */ - public function voidPayment(): void { - if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && !empty($this->request->post['transaction_id'])) { + + public function reauthorizePayment() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + $order_id = (int)$this->request->post['order_id']; - $transaction_id = $this->request->post['transaction_id']; - - $_config = new \Config(); - $_config->load('paypal'); - - $config_setting = $_config->get('paypal_setting'); + $reauthorize_amount = (float)$this->request->post['reauthorize_amount']; + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); - $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - - $client_id = $this->config->get('payment_paypal_client_id'); - $secret = $this->config->get('payment_paypal_secret'); - $environment = $this->config->get('payment_paypal_environment'); - $partner_id = $setting['partner'][$environment]['partner_id']; - $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; - $transaction_method = $setting['general']['transaction_method']; - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, - 'partner_attribution_id' => $partner_attribution_id - ]; - - $paypal = new PayPal($paypal_info); - - $token_info = [ - 'grant_type' => 'client_credentials' - ]; - - $paypal->setAccessToken($token_info); - - $result = $paypal->setPaymentVoid($transaction_id); - - if ($paypal->hasErrors()) { - $error_messages = []; - - $errors = $paypal->getErrors(); - - foreach ($errors as $error) { - if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { - $error['message'] = $this->language->get('error_timeout'); - } - - if (isset($error['details'][0]['description'])) { - $error_messages[] = $error['details'][0]['description']; - } elseif (isset($error['message'])) { - $error_messages[] = $error['message']; + if ($paypal_order_info) { + $transaction_id = $paypal_order_info['transaction_id']; + $currency_code = $paypal_order_info['currency_code']; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + $decimal_place = $setting['currency'][$paypal_order_info['currency_code']]['decimal_place']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $transaction_info = array( + 'amount' => array( + 'value' => number_format($reauthorize_amount, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentReauthorize($transaction_id, $transaction_info); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); } - - $this->model_extension_payment_paypal->log($error, $error['message']); + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($result['id']) && isset($result['status']) && !$this->error) { + $transaction_id = $result['id']; + $transaction_status = 'created'; + + $paypal_order_data = array( + 'order_id' => $order_id, + 'transaction_id' => $transaction_id, + 'transaction_status' => $transaction_status + ); + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $data['success'] = $this->language->get('success_reauthorize_payment'); } - - $this->error['warning'] = implode(' ', $error_messages); } + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function voidPayment() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id'])) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + + $order_id = (int)$this->request->post['order_id']; + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); - if (!$this->error) { - $transaction_status = 'voided'; - - $this->model_extension_payment_paypal->deletePayPalOrder($order_id); - - $paypal_order_data = [ - 'order_id' => $order_id, - 'transaction_status' => $transaction_status - ]; - - $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); - - $json['success'] = $this->language->get('success_void_payment'); + if ($paypal_order_info) { + $transaction_id = $paypal_order_info['transaction_id']; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $result = $paypal->setPaymentVoid($transaction_id); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (!$this->error) { + $transaction_status = 'voided'; + + $paypal_order_data = array( + 'order_id' => $order_id, + 'transaction_status' => $transaction_status + ); + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $data['success'] = $this->language->get('success_void_payment'); + } } } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Refund Payment - * - * @return void - */ - public function refundPayment(): void { - if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && !empty($this->request->post['transaction_id'])) { + + public function refundPayment() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id'])) { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + $this->load->model('sale/order'); + $order_id = (int)$this->request->post['order_id']; - $transaction_id = $this->request->post['transaction_id']; - - $_config = new \Config(); - $_config->load('paypal'); - - $config_setting = $_config->get('paypal_setting'); - - $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - - $client_id = $this->config->get('payment_paypal_client_id'); - $secret = $this->config->get('payment_paypal_secret'); - $environment = $this->config->get('payment_paypal_environment'); - $partner_id = $setting['partner'][$environment]['partner_id']; - $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; - $transaction_method = $setting['general']['transaction_method']; - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, - 'partner_attribution_id' => $partner_attribution_id - ]; - - $paypal = new PayPal($paypal_info); - - $token_info = [ - 'grant_type' => 'client_credentials' - ]; - - $paypal->setAccessToken($token_info); - - $result = $paypal->setPaymentRefund($transaction_id); - - if ($paypal->hasErrors()) { - $error_messages = []; - - $errors = $paypal->getErrors(); - - foreach ($errors as $error) { - if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { - $error['message'] = $this->language->get('error_timeout'); + $refund_amount = (float)$this->request->post['refund_amount']; + + $order_info = $this->model_sale_order->getOrder($order_id); + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); + + if ($order_info && $paypal_order_info) { + $transaction_id = $paypal_order_info['transaction_id']; + $transaction_status = $paypal_order_info['transaction_status']; + $currency_code = $paypal_order_info['currency_code']; + $order_status_id = 0; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + $decimal_place = $setting['currency'][$paypal_order_info['currency_code']]['decimal_place']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $paypal_order_info = $paypal->getOrder($paypal_order_info['paypal_order_id']); + + $capture_refund_amount = array(); + $available_refund_amount = 0; + $final_capture_amount = 0; + + if (isset($paypal_order_info['purchase_units'][0]['payments'])) { + $payments = $paypal_order_info['purchase_units'][0]['payments']; + + if (!empty($payments['refunds'])) { + foreach ($payments['refunds'] as $refund) { + if ($refund['status'] == 'COMPLETED') { + foreach ($refund['links'] as $refund_link) { + if ($refund_link['rel'] == 'up') { + $pos = strpos($refund_link['href'], '/captures/'); + + if ($pos !== false) { + $capture_id = substr($refund_link['href'], $pos + 10); + + if (empty($capture_refund_amount[$capture_id])) { + $capture_refund_amount[$capture_id] = $refund['amount']['value']; + } else { + $capture_refund_amount[$capture_id] += $refund['amount']['value']; + } + } + } + } + } + } } - - if (isset($error['details'][0]['description'])) { - $error_messages[] = $error['details'][0]['description']; - } elseif (isset($error['message'])) { - $error_messages[] = $error['message']; + + if (!empty($payments['captures'])) { + foreach ($payments['captures'] as $capture) { + if (($capture['status'] == 'COMPLETED')) { + $available_refund_amount += $capture['amount']['value']; + } + + if ($capture['status'] == 'PARTIALLY_REFUNDED') { + if (!empty($capture_refund_amount[$capture['id']])) { + $available_refund_amount += ($capture['amount']['value'] - $capture_refund_amount[$capture['id']]); + } + } + + if ($capture['id'] == $transaction_id) { + $final_capture_amount = $capture['amount']['value']; + } + } + } + + if ($refund_amount > $available_refund_amount) { + $transaction_info = array( + 'amount' => array( + 'value' => number_format($refund_amount, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($transaction_id, $transaction_info); + } else { + if (($transaction_status == 'completed') && ($refund_amount < $available_refund_amount) && (count($payments['captures']) > 1)) { + $final_capture_first_amount = 0; + + if ($refund_amount < $final_capture_amount) { + $final_capture_first_amount = $refund_amount * 0.5; + } else { + $final_capture_first_amount = $final_capture_amount * 0.5; + } + + $transaction_info = array( + 'amount' => array( + 'value' => number_format($final_capture_first_amount * 0.5, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($transaction_id, $transaction_info); + + $refund_amount -= ($final_capture_first_amount * 0.5); + } + + if (!empty($payments['captures'])) { + foreach ($payments['captures'] as $capture) { + if ($refund_amount > 0) { + if (($capture['status'] == 'COMPLETED')) { + if ($refund_amount <= $capture['amount']['value']) { + $transaction_info = array( + 'amount' => array( + 'value' => number_format($refund_amount, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($capture['id'], $transaction_info); + + $refund_amount = 0; + } else { + $transaction_info = array( + 'amount' => array( + 'value' => number_format($capture['amount']['value'], $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($capture['id'], $transaction_info); + + $refund_amount -= $capture['amount']['value']; + } + } + + if ($capture['status'] == 'PARTIALLY_REFUNDED') { + if (!empty($capture_refund_amount[$capture['id']])) { + if ($refund_amount <= ($capture['amount']['value'] - $capture_refund_amount[$capture['id']])) { + $transaction_info = array( + 'amount' => array( + 'value' => number_format($refund_amount, $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($capture['id'], $transaction_info); + + $refund_amount = 0; + } else { + $transaction_info = array( + 'amount' => array( + 'value' => number_format($capture['amount']['value'] - $capture_refund_amount[$capture['id']], $decimal_place, '.', ''), + 'currency_code' => $currency_code + ) + ); + + $result = $paypal->setPaymentRefund($capture['id'], $transaction_info); + + $refund_amount -= ($capture['amount']['value'] - $capture_refund_amount[$capture['id']]); + } + } + } + } + } + } } - - $this->model_extension_payment_paypal->log($error, $error['message']); } - - $this->error['warning'] = implode(' ', $error_messages); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($result['id']) && isset($result['status']) && !$this->error) { + $result = $paypal->getPaymentCapture($transaction_id); + + if (!empty($result['status'] == 'REFUNDED')) { + $order_status_id = $setting['order_status']['refunded']['id']; + $transaction_status = 'refunded'; + } elseif (!empty($result['status'] == 'PARTIALLY_REFUNDED')) { + $order_status_id = $setting['order_status']['partially_refunded']['id']; + $transaction_status = 'partially_refunded'; + } + + if ($order_status_id && ($order_info['order_status_id'] != $order_status_id)) { + $this->model_extension_payment_paypal->addOrderHistory($setting['general']['order_history_token'], $order_id, $order_status_id); + } + + $paypal_order_data = array(); + + $paypal_order_data['order_id'] = $order_id; + $paypal_order_data['transaction_status'] = $transaction_status; + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $data['success'] = $this->language->get('success_refund_payment'); + } } + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function autocompleteCarrier() { + $this->load->model('extension/payment/paypal'); + + $data = array(); + + if (!empty($this->request->post['filter_country_code']) && !empty($this->request->post['filter_carrier_name'])) { + $filter_country_code = $this->request->post['filter_country_code']; + $filter_carrier_name = $this->request->post['filter_carrier_name']; + + $_config = new Config(); + $_config->load('paypal_carrier'); + + $config_carrier = $_config->get('paypal_carrier'); + + $carriers = array(); + + if (!empty($config_carrier[$filter_country_code])) { + $carriers = $config_carrier[$filter_country_code]; + } + + $carriers = $carriers + $config_carrier['GLOBAL']; + + foreach ($carriers as $carrier_name => $carrier_code) { + if (strpos(strtolower($carrier_name), strtolower($filter_carrier_name)) !== false) { + $data[] = array( + 'name' => $carrier_name, + 'code' => $carrier_code + ); + } + } + } + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function createTracker() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && !empty($this->request->post['country_code']) && isset($this->request->post['tracking_number']) && isset($this->request->post['carrier_name'])) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + + $order_id = $this->request->post['order_id']; + $country_code = $this->request->post['country_code']; + $tracking_number = $this->request->post['tracking_number']; + $carrier_name = $this->request->post['carrier_name']; + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); - if (isset($result['id']) && isset($result['status']) && !$this->error) { - $transaction_status = 'refunded'; - - $paypal_order_data = [ - 'order_id' => $order_id, - 'transaction_status' => $transaction_status - ]; - - $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); - - $json['success'] = $this->language->get('success_refund_payment'); + if ($paypal_order_info) { + $paypal_order_id = $paypal_order_info['paypal_order_id']; + $transaction_id = $paypal_order_info['transaction_id']; + + $_config = new Config(); + $_config->load('paypal_carrier'); + + $config_carrier = $_config->get('paypal_carrier'); + + $carriers = array(); + + if (!empty($config_carrier[$country_code])) { + $carriers = $config_carrier[$country_code]; + } + + $carriers = $carriers + $config_carrier['GLOBAL']; + + $carrier_code = 'OTHER'; + + if (!empty($carriers[$carrier_name])) { + $carrier_code = $carriers[$carrier_name]; + } + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $tracker_info = array(); + + $tracker_info['capture_id'] = $transaction_id; + $tracker_info['tracking_number'] = $tracking_number; + $tracker_info['carrier'] = $carrier_code; + $tracker_info['notify_payer'] = false; + + if ($carrier_code == 'OTHER') { + $tracker_info['carrier_name_other'] = $carrier_name; + } + + $result = $paypal->createOrderTracker($paypal_order_id, $tracker_info); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($result['id']) && isset($result['status']) && !$this->error) { + $paypal_order_data = array( + 'order_id' => $order_id, + 'tracking_number' => $tracking_number, + 'carrier_name' => $carrier_name + ); + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $this->load->model('sale/order'); + + $order_info = $this->model_sale_order->getOrder($order_id); + + if ($order_info) { + $order_status_id = $setting['order_status']['shipped']['id']; + + if ($order_info['order_status_id'] != $order_status_id) { + $this->model_extension_payment_paypal->addOrderHistory($setting['general']['order_history_token'], $order_id, $order_status_id); + } + } + + $data['success'] = $this->language->get('success_create_tracker'); + } } } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Recurring Buttons - * - * @return string - */ - public function recurringButtons(): string { - $content = ''; - - if ($this->config->get('payment_paypal_status')) { + + public function cancelTracker() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_id']) && isset($this->request->post['tracking_number'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); + + $order_id = $this->request->post['order_id']; + $tracking_number = $this->request->post['tracking_number']; + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); - if (isset($this->request->get['order_recurring_id'])) { - $order_recurring_id = (int)$this->request->get['order_recurring_id']; - } else { - $order_recurring_id = 0; + if ($paypal_order_info) { + $paypal_order_id = $paypal_order_info['paypal_order_id']; + $transaction_id = $paypal_order_info['transaction_id']; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $transaction_method = $setting['general']['transaction_method']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $tracker_info = array(); + + $tracker_info[] = array( + 'op' => 'replace', + 'path' => '/status', + 'value' => 'CANCELLED' + ); + + $result = $paypal->updateOrderTracker($paypal_order_id, $transaction_id . '-' . $tracking_number, $tracker_info); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (!$this->error) { + $paypal_order_data = array( + 'order_id' => $order_id, + 'tracking_number' => '', + 'carrier_name' => '' + ); + + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $data['success'] = $this->language->get('success_cancel_tracker'); + } } + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function recurringButtons() { + $content = ''; + + if ($this->config->get('payment_paypal_status') && !empty($this->request->get['order_recurring_id'])) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('sale/recurring'); + + $data['order_recurring_id'] = $this->request->get['order_recurring_id']; - $data['order_recurring_id'] = $order_recurring_id; - - $this->load->model('extension/other/recurring'); - - $order_recurring_info = $this->model_extension_other_recurring->getRecurring($order_recurring_id); - + $order_recurring_info = $this->model_sale_recurring->getRecurring($data['order_recurring_id']); + if ($order_recurring_info) { - $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_recurring_info['order_id']); - - $data['subscription_status'] = $paypal_order_info['status']; - - $data['info_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getRecurringInfo', 'user_token=' . $this->session->data['user_token'] . '&order_recurring_id=' . $order_recurring_id, true)); + $data['recurring_status'] = $order_recurring_info['status']; + + $data['info_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/getRecurringInfo', 'user_token=' . $this->session->data['user_token'] . '&order_recurring_id=' . $data['order_recurring_id'], true)); $data['enable_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/enableRecurring', 'user_token=' . $this->session->data['user_token'], true)); $data['disable_url'] = str_replace('&', '&', $this->url->link('extension/payment/paypal/disableRecurring', 'user_token=' . $this->session->data['user_token'], true)); - - $content = $this->load->view('extension/payment/paypal/subscription', $data); + + $content = $this->load->view('extension/payment/paypal/recurring', $data); } } - + return $content; } - - /** - * Get Recurring Info - * - * @return void - */ - public function getRecurringInfo(): void { + + public function getRecurringInfo() { $this->response->setOutput($this->recurringButtons()); } - - /** - * Enable Subscription - * - * @return void - */ - public function enableRecurring(): void { - $json = []; - - if ($this->config->get('payment_paypal_status')) { + + public function enableRecurring() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_recurring_id'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - - if (isset($this->request->get['order_recurring_id'])) { - $order_recurring_id = (int)$this->request->get['order_recurring_id']; - } else { - $order_recurring_id = 0; - } - - $this->load->model('extension/other/recurring'); - - $order_recurring_info = $this->model_extension_other_recurring->getRecurring($order_recurring_id); - - $this->model_extension_payment_paypal->editOrderSubscriptionStatus($order_recurring_info['order_id'], 1); - - $json['success'] = $this->language->get('success_enable_recurring'); - } - - $json['error'] = $this->error; - + + $order_recurring_id = $this->request->post['order_recurring_id']; + + $this->model_extension_payment_paypal->editOrderRecurringStatus($order_recurring_id, 1); + + $data['success'] = $this->language->get('success_enable_recurring'); + } + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Disable Subscription - * - * @return void - */ - public function disableRecurring(): void { - $json = []; - - if ($this->config->get('payment_paypal_status')) { + + public function disableRecurring() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_recurring_id'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - - if (isset($this->request->get['order_recurring_id'])) { - $order_recurring_id = (int)$this->request->get['order_recurring_id']; - } else { - $order_recurring_id = 0; - } - - $this->load->model('extension/other/recurring'); - - $order_recurring_info = $this->model_extension_other_recurring->getRecurring($order_recurring_id); - - $this->model_extension_payment_paypal->editOrderSubscriptionStatus($order_recurring_info['order_id'], 2); - - $json['success'] = $this->language->get('success_disable_subscription'); - } - - $json['error'] = $this->error; - + + $order_recurring_id = $this->request->post['order_recurring_id']; + + $this->model_extension_payment_paypal->editOrderRecurringStatus($order_recurring_id, 2); + + $data['success'] = $this->language->get('success_disable_recurring'); + } + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Validate - * - * @return bool - */ - private function validate(): bool { + + private function validate() { if (!$this->user->hasPermission('modify', 'extension/payment/paypal')) { $this->error['warning'] = $this->language->get('error_permission'); } - + return !$this->error; } - - /** - * Token - * - * @param int $length - * - * @return string - */ - private function token(int $length = 32): string { + + private function token($length = 32) { // Create random token $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - + $max = strlen($string) - 1; - + $token = ''; - + for ($i = 0; $i < $length; $i++) { $token .= $string[mt_rand(0, $max)]; - } - + } + return $token; } -} +} \ No newline at end of file diff --git a/upload/admin/language/en-gb/extension/payment/paypal.php b/upload/admin/language/en-gb/extension/payment/paypal.php index aa08d165e..376519c28 100644 --- a/upload/admin/language/en-gb/extension/payment/paypal.php +++ b/upload/admin/language/en-gb/extension/payment/paypal.php @@ -1,6 +1,6 @@ PayPal Checkout Integration (Highly Recommended)'; +$_['heading_title'] = 'PayPal Checkout Integration (Highly Recommended)'; $_['heading_title_main'] = 'PayPal Checkout Integration'; // Text @@ -17,7 +17,8 @@ $_['text_tab_googlepay_button'] = 'Google Pay'; $_['text_tab_applepay_button'] = 'Apple Pay'; $_['text_tab_card'] = 'Advanced Cards'; -$_['text_tab_message'] = 'Pay Later messaging'; +$_['text_tab_message_configurator'] = 'Pay Later Messaging'; +$_['text_tab_message_setting'] = 'Pay Later Messaging advanced'; $_['text_tab_order_status'] = 'Order Statuses'; $_['text_tab_contact'] = 'Contact PayPal'; $_['text_all_sales'] = 'All Sales'; @@ -41,19 +42,22 @@ $_['text_cart'] = 'Cart'; $_['text_product'] = 'Product'; $_['text_home'] = 'Home'; +$_['text_automatic'] = 'Automatic'; +$_['text_manual'] = 'Manual'; +$_['text_sandbox'] = 'Sandbox'; $_['text_production'] = 'Production'; $_['text_sandbox'] = 'Sandbox'; $_['text_multi_button'] = 'Multi Button'; $_['text_one_button'] = 'One Button'; $_['text_authorization'] = 'Authorization'; $_['text_sale'] = 'Sale'; -$_['text_connect'] = 'Your seller account has been connected.
Client ID = %s
Secret = %s
Merchant ID = %s
Webhook ID = %s
Environment = %s
If you would like to connect another account, please, disconnect.'; +$_['text_connect'] = 'Your seller account has been connected.
Merchant ID = %s
Client ID = %s
Secret = %s
Webhook ID = %s
Environment = %s
If you would like to connect another account, please, disconnect.'; $_['text_applepay_alert'] = 'You need to verify any domain names in your environment that will show an Apple Pay button.

If Apple hasn’t verified a domain, they will reject any payments from that domain. The Apple Pay payment method won’t work if the domain isn’t registered.'; $_['text_applepay_step_1'] = 'Download and host live domain association file
1. Download the domain association file for your live environment.
2. Host the file on your production site at /.well-known/apple-developer-merchantid-domain-association.'; $_['text_applepay_step_2'] = 'Register your live domain
1. Go to the Payment Methods page on your PayPal account.
2. Register all high-level domains such as business.example.com, and subdomains such as checkout.business.example.com, that show the Apple Pay button.'; $_['text_message_alert_uk'] = 'Turn browsers into buyers with Pay in 3.¹ Help increase sales while giving your customers flexible payments and more buying power. With Pay in 3, customers can pay over time in three interest-free payments while you get paid in full, up front on purchases — at no additional cost.'; $_['text_message_footnote_uk'] = '¹Pay in 3 availability is subject to merchant status, sector and integration. Consumer eligibility is subject to status and approval. See product terms for more details.'; -$_['text_message_alert_us'] = "Help increase your sales with our built-in Pay Later options.\u{a0}With PayPal Pay Later, your business can offer Pay in 4 and Pay Monthly¹ — two valuable ways for your customers to make a purchase and pay for it over time while you get paid in full, up front. Both are included at no additional cost to your business."; +$_['text_message_alert_us'] = 'Help increase your sales with our built-in Pay Later options. With PayPal Pay Later, your business can offer Pay in 4 and Pay Monthly¹ — two valuable ways for your customers to make a purchase and pay for it over time while you get paid in full, up front. Both are included at no additional cost to your business.'; $_['text_message_footnote_us'] = '¹About Pay in 4: Loans to California residents are made or arranged pursuant to a California Financing Law License. PayPal, Inc. is a Georgia Installment Lender Licensee, NMLS #910457. Rhode Island Small Loan Lender Licensee.
Pay Monthly is subject to consumer credit approval. 9.99-29.99% APR based on the customer’s creditworthiness. PayPal, Inc.: RI Loan Broker Licensee. The lender for Pay Monthly is WebBank.'; $_['text_currency_aud'] = 'Australian Dollar'; $_['text_currency_brl'] = 'Brazilian Real'; @@ -84,9 +88,12 @@ $_['text_denied_status'] = 'Denied Status'; $_['text_failed_status'] = 'Failed Status'; $_['text_pending_status'] = 'Pending Status'; +$_['text_partially_captured_status'] = 'Partially Captured Status'; +$_['text_partially_refunded_status'] = 'Partially Refunded Status'; $_['text_refunded_status'] = 'Refunded Status'; $_['text_reversed_status'] = 'Reversed Status'; $_['text_voided_status'] = 'Voided Status'; +$_['text_shipped_status'] = 'Shipped Status'; $_['text_insert_prepend'] = 'Insert Into Begin'; $_['text_insert_append'] = 'Insert Into End'; $_['text_insert_before'] = 'Insert Before'; @@ -126,7 +133,6 @@ $_['text_mybank'] = 'MyBank'; $_['text_p24'] = 'Przelewy24'; $_['text_sepa'] = 'SEPA-Lastschrift'; -$_['text_sofort'] = 'Sofort'; $_['text_venmo'] = 'Venmo'; $_['text_paylater'] = 'Pay Later'; $_['text_auto'] = 'Auto'; @@ -134,6 +140,8 @@ $_['text_flex'] = 'Flexible Banner'; $_['text_accept'] = 'Accept'; $_['text_decline'] = 'Decline'; +$_['text_sca_when_required'] = 'SCA When Required'; +$_['text_sca_always'] = 'SCA Always'; $_['text_recommended'] = '(recommended)'; $_['text_3ds_failed_authentication'] = 'Failed authentication.'; $_['text_3ds_rejected_authentication'] = 'Rejected authentication.'; @@ -190,25 +198,42 @@ $_['text_step_shipping'] = 'Estimate Shipping & Taxes'; $_['text_step_payment_method'] = 'Step 5: Payment Method'; $_['text_step_confirm_order'] = 'Step 6: Confirm Order'; +$_['text_payment_information'] = 'Payment Information'; $_['text_transaction_id'] = 'Transaction ID'; +$_['text_transaction_description'] = 'Transaction Description'; $_['text_transaction_created'] = 'Payment authorization was created.'; $_['text_transaction_voided'] = 'Payment authorization was voided.'; +$_['text_transaction_partially_captured'] = 'Payment authorization was partially captured.'; $_['text_transaction_completed'] = 'Payment capture was completed.'; $_['text_transaction_declined'] = 'Payment capture was declined.'; $_['text_transaction_pending'] = 'The state of a payment capture was changed to pending.'; $_['text_transaction_refunded'] = 'A merchant refunded the payment capture.'; +$_['text_transaction_partially_refunded'] = 'A merchant partially refunded the payment capture.'; $_['text_transaction_reversed'] = 'PayPal reversed the payment capture.'; +$_['text_transaction_action'] = 'Action'; +$_['text_final_capture'] = 'Final Capture'; +$_['text_tracker_information'] = 'Tracking Information'; +$_['text_tracking_number'] = 'Tracking Number'; +$_['text_carrier_name'] = 'Carrier'; +$_['text_tracker_action'] = 'Action'; +$_['text_loading'] = 'Loading...'; // Entry $_['entry_connect'] = 'Connect'; +$_['entry_authorization_type'] = 'Authorization Type'; $_['entry_environment'] = 'Environment'; +$_['entry_merchant_id'] = 'Merchant ID'; +$_['entry_client_id'] = 'Client ID'; +$_['entry_client_secret'] = 'Secret'; +$_['entry_status'] = 'Status'; +$_['entry_vault_status'] = 'Vault Status'; $_['entry_debug'] = 'Debug Logging'; $_['entry_sale_analytics_range'] = 'Sales Analytics Range'; $_['entry_checkout_mode'] = 'Checkout Mode'; +$_['entry_checkout_route'] = 'Checkout Route'; $_['entry_transaction_method'] = 'Settlement Method'; $_['entry_total'] = 'Total'; $_['entry_geo_zone'] = 'Geo Zone'; -$_['entry_status'] = 'Status'; $_['entry_sort_order'] = 'Sort Order'; $_['entry_country_code'] = 'Country'; $_['entry_currency_code'] = 'Currency'; @@ -224,11 +249,15 @@ $_['entry_button_shape'] = 'Button Shape'; $_['entry_button_label'] = 'Button Label'; $_['entry_button_tagline'] = 'Button Tagline'; +$_['entry_googlepay_button_insert_tag'] = 'Button Insert Tag'; +$_['entry_googlepay_button_insert_type'] = 'Button Insert Type'; $_['entry_googlepay_button_align'] = 'Button Align'; $_['entry_googlepay_button_size'] = 'Button Size'; $_['entry_googlepay_button_color'] = 'Button Color'; $_['entry_googlepay_button_shape'] = 'Button Shape'; $_['entry_googlepay_button_type'] = 'Button Type'; +$_['entry_applepay_button_insert_tag'] = 'Button Insert Tag'; +$_['entry_applepay_button_insert_type'] = 'Button Insert Type'; $_['entry_applepay_button_align'] = 'Button Align'; $_['entry_applepay_button_size'] = 'Button Size'; $_['entry_applepay_button_color'] = 'Button Color'; @@ -236,20 +265,13 @@ $_['entry_applepay_button_type'] = 'Button Type'; $_['entry_card_align'] = 'Card Align'; $_['entry_card_size'] = 'Card Size'; -$_['entry_card_secure_status'] = 'Card 3D Secure Status'; +$_['entry_card_secure_method'] = 'Card 3D Secure Method'; $_['entry_card_secure_scenario'] = 'Card 3D Secure Scenarios'; $_['entry_card_number'] = 'Card Number'; $_['entry_expiration_date'] = 'Expiration Date'; $_['entry_cvv'] = 'CVV'; $_['entry_message_insert_tag'] = 'Message Insert Tag'; $_['entry_message_insert_type'] = 'Message Insert Type'; -$_['entry_message_align'] = 'Message Align'; -$_['entry_message_size'] = 'Message Size'; -$_['entry_message_layout'] = 'Message Layout'; -$_['entry_message_text_color'] = 'Message Text Color'; -$_['entry_message_text_size'] = 'Message Text Size'; -$_['entry_message_flex_color'] = 'Message Banner Color'; -$_['entry_message_flex_ratio'] = 'Message Banner Ratio'; $_['entry_contact_company'] = 'Company'; $_['entry_contact_first_name'] = 'First Name'; $_['entry_contact_last_name'] = 'Last Name'; @@ -266,26 +288,28 @@ // Help $_['help_status'] = 'Enable/Disable extension.'; +$_['help_vault_status'] = 'Vault allows merchant to securely save buyer’s payment method for future transactions. Vault substitutes the sensitive payment data with non-sensitive payment token and allows merchant to use the payment Token for future purchases.'; $_['help_button_status'] = 'When activated PayPal will display personalized Smart Buttons avalible to your customers based on their location.'; $_['help_googlepay_button_status'] = 'PayPal verifies if you are eligible for Google Pay payment and will display this option on the checkout step if available.'; $_['help_applepay_button_status'] = 'PayPal verifies if you are eligible for Apple Pay payment and will display this option on the checkout step if available.'; $_['help_card_status'] = 'PayPal verifies if you are eligible for advanced card payment and will display this option on the checkout step if available.'; -$_['help_message_status'] = 'Add pay later messaging to your site.'; $_['help_checkout_mode'] = 'If your checkout is incompatible with this payment, then we advise you to set the \'One Button\' mode.'; +$_['help_checkout_route'] = 'If your checkout has its own route, different from OpenCart\'s (checkout/checkout), then enter it here.'; $_['help_total'] = 'The checkout total the order must reach before this payment method becomes active.'; $_['help_country_code'] = 'Select the default country for PayPal.'; $_['help_currency_code'] = 'Select the default currency for PayPal.'; $_['help_currency_value'] = 'Set to 1.00000 if this is your default currency.'; $_['help_card_currency_code'] = 'Select the default currency for PayPal Card.'; $_['help_card_currency_value'] = 'Set to 1.00000 if this is your default currency.'; -$_['help_cron_url'] = 'Set a cron to call this URL.'; -$_['help_card_secure_status'] = '3D Secure enables you to authenticate card holders through card issuers. It reduces the likelihood of fraud when you use supported cards and improves transaction perfomance. A successful 3D Secure authentication can shift liability for chargebacks due to fraud from you -the merchant- to the card issuer.'; +$_['help_cron_url'] = 'Set a cron to call this URL. This integration is typically used for subscription/recurring product purchase.'; +$_['help_card_secure_method'] = '3D Secure enables you to authenticate card holders through card issuers. \'SCA Always\' method trigger 3D Secure for every transaction, regardless of SCA requirements. \'SCA When Required\' method returns a 3D Secure contingency when it is a mandate in the region where you operate.'; $_['help_card_secure_scenario'] = '3D Secure authentication is perfomed only if the card is enrolled for the service. In scenarios where the 3D Secure authentication has not been successful, you have the option to complete the payment at your own risk, meaning that you -the merchant- will be liable in case of a chargeback.'; // Button $_['button_connect'] = 'Connect'; $_['button_disconnect'] = 'Disconnect'; $_['button_all_settings'] = 'All Settings'; +$_['button_view'] = 'View'; $_['button_copy_url'] = 'Copy URL to clipboard'; $_['button_download'] = 'Download'; $_['button_download_host'] = 'Download and host'; @@ -297,8 +321,10 @@ $_['button_reauthorize_payment'] = 'Reauthorize'; $_['button_void_payment'] = 'Void'; $_['button_refund_payment'] = 'Refund'; -$_['button_enable_subscription'] = 'Enable Subscription'; -$_['button_disable_subscription'] = 'Disable Subscription'; +$_['button_create_tracker'] = 'Add Tracking Information'; +$_['button_cancel_tracker'] = 'Cancel Tracking Information'; +$_['button_enable_recurring'] = 'Enable Recurring'; +$_['button_disable_recurring'] = 'Disable Recurring'; // Success $_['success_save'] = 'Success: You have modified PayPal!'; @@ -309,10 +335,13 @@ $_['success_reauthorize_payment'] = 'Success: Payment authorization was reauthorized.'; $_['success_void_payment'] = 'Success: Payment authorization was voided.'; $_['success_refund_payment'] = 'Success: Payment capture was refunded.'; -$_['success_enable_subscription'] = 'Success: Subscription payment was enabled.'; -$_['success_disable_subscription'] = 'Success: Subscription payment was disabled.'; +$_['success_create_tracker'] = 'Success: Tracking information has been added successfully.'; +$_['success_cancel_tracker'] = 'Success: Tracking information has been cancelled successfully.'; +$_['success_enable_recurring'] = 'Success: Recurring payment was enabled.'; +$_['success_disable_recurring'] = 'Success: Recurring payment was disabled.'; // Error $_['error_permission'] = 'Warning: You do not have permission to modify payment PayPal!'; +$_['error_connect'] = 'Warning: Client ID or Secret is incorrect!'; $_['error_timeout'] = 'Sorry, PayPal is currently busy. Please try again later!'; -$_['error_agree'] = 'We discovered that a few countries under sanctions are featured on your website. Please click the button to deactivate them (Cuba, Iran, Syria, North Korea, Crimea, Donetsk, and Lugansk regions of Ukraine).

'; +$_['error_agree'] = 'We discovered that a few countries under sanctions are featured on your website. Please click the button to deactivate them (Cuba, Iran, Syria, North Korea, Crimea, Donetsk, and Lugansk regions of Ukraine).

'; \ No newline at end of file diff --git a/upload/admin/model/extension/payment/paypal.php b/upload/admin/model/extension/payment/paypal.php index c92282ce4..9505caa21 100644 --- a/upload/admin/model/extension/payment/paypal.php +++ b/upload/admin/model/extension/payment/paypal.php @@ -1,362 +1,331 @@ config->get('config_complete_status') as $order_status_id) { + + public function getTotalSales() { + $implode = array(); + + foreach ($this->config->get('config_complete_status') as $order_status_id) { $implode[] = "'" . (int)$order_status_id . "'"; } + + $query = $this->db->query("SELECT SUM(total) AS paypal_total FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(',', $implode) . ") AND payment_code = 'paypal'"); - $query = $this->db->query("SELECT SUM(`total`) AS `total` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` IN(" . implode(',', $implode) . ") AND `payment_code` = 'paypal'"); - - if ($query->num_rows) { - return (int)$query->row['total']; - } else { - return 0; - } + return $query->row['paypal_total']; } + + public function getTotalSalesByDay() { + $implode = array(); - /** - * Get Total Sales By Day - * - * @return array> - */ - public function getTotalSalesByDay(): array { - $implode = []; - - foreach ((array)$this->config->get('config_complete_status') as $order_status_id) { + foreach ($this->config->get('config_complete_status') as $order_status_id) { $implode[] = "'" . (int)$order_status_id . "'"; } - $sale_data = []; + $sale_data = array(); for ($i = 0; $i < 24; $i++) { - $sale_data[$i] = [ - 'hour' => $i, - 'total' => 0, - 'paypal_total' => 0 - ]; + $sale_data[$i] = array( + 'hour' => $i, + 'total' => 0, + 'paypal_total' => 0 + ); } - $query = $this->db->query("SELECT SUM(`total`) AS `total`, SUM(IF (`payment_code` = 'paypal', `total`, 0)) AS `paypal_total`, HOUR(`date_added`) AS `hour` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` IN(" . implode(',', $implode) . ") AND DATE(`date_added`) = DATE(NOW()) GROUP BY HOUR(`date_added`) ORDER BY `date_added` ASC"); + $query = $this->db->query("SELECT SUM(total) AS total, SUM(IF (payment_code = 'paypal', total, 0)) AS paypal_total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(',', $implode) . ") AND DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC"); foreach ($query->rows as $result) { - $sale_data[$result['hour']] = [ - 'hour' => $result['hour'], - 'total' => $result['total'], - 'paypal_total' => $result['paypal_total'] - ]; + $sale_data[$result['hour']] = array( + 'hour' => $result['hour'], + 'total' => $result['total'], + 'paypal_total' => $result['paypal_total'] + ); } return $sale_data; } - /** - * Get Total Sales By Week - * - * @return array> - */ - public function getTotalSalesByWeek(): array { - $implode = []; + public function getTotalSalesByWeek() { + $implode = array(); - foreach ((array)$this->config->get('config_complete_status') as $order_status_id) { + foreach ($this->config->get('config_complete_status') as $order_status_id) { $implode[] = "'" . (int)$order_status_id . "'"; } - $sale_data = []; + $sale_data = array(); $date_start = strtotime('-' . date('w') . ' days'); for ($i = 0; $i < 7; $i++) { $date = date('Y-m-d', $date_start + ($i * 86400)); - $sale_data[date('w', strtotime($date))] = [ - 'day' => date('D', strtotime($date)), - 'total' => 0, - 'paypal_total' => 0 - ]; + $sale_data[date('w', strtotime($date))] = array( + 'day' => date('D', strtotime($date)), + 'total' => 0, + 'paypal_total' => 0 + ); } - $query = $this->db->query("SELECT SUM(`total`) AS `total`, SUM(IF (`payment_code` = 'paypal', total, 0)) AS `paypal_total`, `date_added` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` IN(" . implode(',', $implode) . ") AND DATE(`date_added`) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(`date_added`)"); + $query = $this->db->query("SELECT SUM(total) AS total, SUM(IF (payment_code = 'paypal', total, 0)) AS paypal_total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(',', $implode) . ") AND DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)"); foreach ($query->rows as $result) { - $sale_data[date('w', strtotime($result['date_added']))] = [ - 'day' => date('D', strtotime($result['date_added'])), - 'total' => $result['total'], - 'paypal_total' => $result['paypal_total'] - ]; + $sale_data[date('w', strtotime($result['date_added']))] = array( + 'day' => date('D', strtotime($result['date_added'])), + 'total' => $result['total'], + 'paypal_total' => $result['paypal_total'] + ); } return $sale_data; } - /** - * Get Total Sales By Month - * - * @return array> - */ - public function getTotalSalesByMonth(): array { - $implode = []; + public function getTotalSalesByMonth() { + $implode = array(); - foreach ((array)$this->config->get('config_complete_status') as $order_status_id) { + foreach ($this->config->get('config_complete_status') as $order_status_id) { $implode[] = "'" . (int)$order_status_id . "'"; } - $sale_data = []; + $sale_data = array(); for ($i = 1; $i <= date('t'); $i++) { $date = date('Y') . '-' . date('m') . '-' . $i; - $sale_data[date('j', strtotime($date))] = [ - 'day' => date('d', strtotime($date)), - 'total' => 0, - 'paypal_total' => 0 - ]; + $sale_data[date('j', strtotime($date))] = array( + 'day' => date('d', strtotime($date)), + 'total' => 0, + 'paypal_total' => 0 + ); } - $query = $this->db->query("SELECT SUM(`total`) AS `total`, SUM(IF (`payment_code` = 'paypal', total, 0)) AS `paypal_total`, `date_added` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` IN(" . implode(',', $implode) . ") AND DATE(`date_added`) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(`date_added`)"); + $query = $this->db->query("SELECT SUM(total) AS total, SUM(IF (payment_code = 'paypal', total, 0)) AS paypal_total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(',', $implode) . ") AND DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)"); foreach ($query->rows as $result) { - $sale_data[date('j', strtotime($result['date_added']))] = [ - 'day' => date('d', strtotime($result['date_added'])), - 'total' => $result['total'], - 'paypal_total' => $result['paypal_total'] - ]; + $sale_data[date('j', strtotime($result['date_added']))] = array( + 'day' => date('d', strtotime($result['date_added'])), + 'total' => $result['total'], + 'paypal_total' => $result['paypal_total'] + ); } return $sale_data; } - /** - * Get Total Sales By Year - * - * @return array> - */ - public function getTotalSalesByYear(): array { - $implode = []; + public function getTotalSalesByYear() { + $implode = array(); - foreach ((array)$this->config->get('config_complete_status') as $order_status_id) { + foreach ($this->config->get('config_complete_status') as $order_status_id) { $implode[] = "'" . (int)$order_status_id . "'"; } - $sale_data = []; + $sale_data = array(); for ($i = 1; $i <= 12; $i++) { - $sale_data[$i] = [ - 'month' => date('M', mktime(0, 0, 0, $i)), - 'total' => 0, - 'paypal_total' => 0 - ]; + $sale_data[$i] = array( + 'month' => date('M', mktime(0, 0, 0, $i)), + 'total' => 0, + 'paypal_total' => 0 + ); } - $query = $this->db->query("SELECT SUM(`total`) AS `total`, SUM(IF (`payment_code` = 'paypal', `total`, 0)) AS `paypal_total`, `date_added` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` IN(" . implode(',', $implode) . ") AND YEAR(`date_added`) = YEAR(NOW()) GROUP BY MONTH(`date_added`)"); + $query = $this->db->query("SELECT SUM(total) AS total, SUM(IF (payment_code = 'paypal', total, 0)) AS paypal_total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(',', $implode) . ") AND YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)"); foreach ($query->rows as $result) { - $sale_data[date('n', strtotime($result['date_added']))] = [ - 'month' => date('M', strtotime($result['date_added'])), - 'total' => $result['total'], - 'paypal_total' => $result['paypal_total'] - ]; + $sale_data[date('n', strtotime($result['date_added']))] = array( + 'month' => date('M', strtotime($result['date_added'])), + 'total' => $result['total'], + 'paypal_total' => $result['paypal_total'] + ); } return $sale_data; } - - /** - * Get Country By Code - * - * @param string $code - * - * @return array - */ - public function getCountryByCode(string $code): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `iso_code_2` = '" . $this->db->escape($code) . "'"); - + + public function getCountryByCode($code) { + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country WHERE iso_code_2 = '" . $this->db->escape($code) . "'"); + return $query->row; } - - /** - * Edit Paypal Order - * - * @param array $data - * - * @return void - */ - public function editPayPalOrder(array $data): void { + + public function deletePayPalCustomerTokens($customer_id) { + $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "'"); + } + + public function editPayPalOrder($data) { $sql = "UPDATE `" . DB_PREFIX . "paypal_checkout_integration_order` SET"; - $implode = []; - + $implode = array(); + + if (!empty($data['paypal_order_id'])) { + $implode[] = "`paypal_order_id` = '" . $this->db->escape($data['paypal_order_id']) . "'"; + } + if (!empty($data['transaction_id'])) { $implode[] = "`transaction_id` = '" . $this->db->escape($data['transaction_id']) . "'"; } - + if (!empty($data['transaction_status'])) { $implode[] = "`transaction_status` = '" . $this->db->escape($data['transaction_status']) . "'"; } - + if (!empty($data['payment_method'])) { $implode[] = "`payment_method` = '" . $this->db->escape($data['payment_method']) . "'"; } - + if (!empty($data['vault_id'])) { $implode[] = "`vault_id` = '" . $this->db->escape($data['vault_id']) . "'"; } - + if (!empty($data['vault_customer_id'])) { $implode[] = "`vault_customer_id` = '" . $this->db->escape($data['vault_customer_id']) . "'"; } - + + if (!empty($data['card_type'])) { + $implode[] = "`card_type` = '" . $this->db->escape($data['card_type']) . "'"; + } + + if (!empty($data['card_nice_type'])) { + $implode[] = "`card_nice_type` = '" . $this->db->escape($data['card_nice_type']) . "'"; + } + + if (!empty($data['card_last_digits'])) { + $implode[] = "`card_last_digits` = '" . $this->db->escape($data['card_last_digits']) . "'"; + } + + if (!empty($data['card_expiry'])) { + $implode[] = "`card_expiry` = '" . $this->db->escape($data['card_expiry']) . "'"; + } + + if (!empty($data['total'])) { + $implode[] = "`total` = '" . (float)$data['total'] . "'"; + } + + if (!empty($data['currency_code'])) { + $implode[] = "`currency_code` = '" . $this->db->escape($data['currency_code']) . "'"; + } + if (!empty($data['environment'])) { $implode[] = "`environment` = '" . $this->db->escape($data['environment']) . "'"; } - + + if (isset($data['tracking_number'])) { + $implode[] = "`tracking_number` = '" . $this->db->escape($data['tracking_number']) . "'"; + } + + if (isset($data['carrier_name'])) { + $implode[] = "`carrier_name` = '" . $this->db->escape($data['carrier_name']) . "'"; + } + if ($implode) { $sql .= implode(", ", $implode); } $sql .= " WHERE `order_id` = '" . (int)$data['order_id'] . "'"; - + $this->db->query($sql); } - - /** - * Delete PayPal Order - * - * @param int $order_id - * - * @return void - */ - public function deletePayPalOrder(int $order_id): void { + + public function deletePayPalOrder($order_id) { $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `order_id` = '" . (int)$order_id . "'"); } - - /** - * Get PayPal Order - * - * @param int $order_id - * - * @return array - */ - public function getPayPalOrder(int $order_id): array { + + public function getPayPalOrder($order_id) { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `order_id` = '" . (int)$order_id . "'"); - + if ($query->num_rows) { return $query->row; } else { - return []; + return array(); } } - - /** - * Get PayPal Order Subscription - * - * @param int $order_id - * - * @return array - */ - public function getPayPalOrderSubscription(int $order_id): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` WHERE `order_id` = '" . (int)$order_id . "'"); - - return $query->row; - } - - /** - * Edit Order Subscription Status - * - * @param int $order_id - * @param int $status - * - * @return void - */ - public function editOrderSubscriptionStatus(int $order_id, int $status): void { - $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_order` SET `status` = '" . (int)$status . "' WHERE `order_id` = '" . (int)$order_id . "'"); + + public function editOrderRecurringStatus($order_recurring_id, $status) { + $this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = '" . (int)$status . "' WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); } - - /** - * Set Agree Status - * - * @return void - */ - public function setAgreeStatus(): void { - $this->db->query("UPDATE `" . DB_PREFIX . "country` SET `status` = '0' WHERE (`iso_code_2` = 'CU' OR `iso_code_2` = 'IR' OR `iso_code_2` = 'SY' OR `iso_code_2` = 'KP')"); - $this->db->query("UPDATE `" . DB_PREFIX . "zone` SET `status` = '0' WHERE `country_id` = '220' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); + + public function setAgreeStatus() { + $this->db->query("UPDATE " . DB_PREFIX . "country SET status = '0' WHERE (iso_code_2 = 'CU' OR iso_code_2 = 'IR' OR iso_code_2 = 'SY' OR iso_code_2 = 'KP')"); + $this->db->query("UPDATE " . DB_PREFIX . "zone SET status = '0' WHERE country_id = '220' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); } - - /** - * Get Agree Status - * - * @return bool - */ - public function getAgreeStatus(): bool { + + public function getAgreeStatus() { $agree_status = true; - - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `status` = '1' AND (`iso_code_2` = 'CU' OR `iso_code_2` = 'IR' OR `iso_code_2` = 'SY' OR `iso_code_2` = 'KP')"); - + + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country WHERE status = '1' AND (iso_code_2 = 'CU' OR iso_code_2 = 'IR' OR iso_code_2 = 'SY' OR iso_code_2 = 'KP')"); + if ($query->rows) { $agree_status = false; } - - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE `country_id` = '220' AND `status` = '1' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); - + + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone WHERE country_id = '220' AND status = '1' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); + if ($query->rows) { $agree_status = false; } - + return $agree_status; } - - /** - * Check Version - * - * @param string $opencart_version - * @param string $paypal_version - * - * @return array - */ - public function checkVersion(string $opencart_version, string $paypal_version): array { + + public function addOrderHistory($order_history_token, $order_id, $order_status_id) { + if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) { + $catalog = HTTPS_CATALOG; + } else { + $catalog = HTTP_CATALOG; + } + + $data = array( + 'order_id' => $order_id, + 'order_status_id' => $order_status_id + ); + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, $catalog . 'index.php?route=extension/payment/paypal/addOrderHistory&order_history_token=' . $order_history_token); + curl_setopt($curl, CURLOPT_HEADER, 0); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); + curl_setopt($curl, CURLOPT_FORBID_REUSE, 1); + curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); + $response = curl_exec($curl); + + curl_close($curl); + + $result = json_decode($response, true); + + if (!empty($result['success'])) { + return true; + } else { + return false; + } + } + + public function checkVersion($opencart_version, $paypal_version) { + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, 'https://www.opencart.com/index.php?route=api/promotion/paypalCheckoutIntegration&opencart=' . $opencart_version . '&paypal=' . $paypal_version); curl_setopt($curl, CURLOPT_HEADER, 0); - curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); curl_setopt($curl, CURLOPT_FORBID_REUSE, 1); curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1); - + $response = curl_exec($curl); - + curl_close($curl); - + $result = json_decode($response, true); - + if ($result) { return $result; } else { - return []; + return false; } } - - /** - * Send Contact - * - * @param array $data - * - * @return void - */ - public function sendContact(array $data): void { + + public function sendContact($data) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8'); @@ -373,109 +342,47 @@ public function sendContact(array $data): void { curl_close($curl); } - - /** - * Log - * - * @param array $data - * @param string $title - * - * @return void - */ - public function log(array $data, ?string $title = null): void { - $_config = new \Config(); + + public function log($data, $title = null) { + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + if ($setting['general']['debug']) { - $log = new \Log('paypal.log'); + $log = new Log('paypal.log'); $log->write('PayPal debug (' . $title . '): ' . json_encode($data)); } } - - /** - * Install - * - * @return void - */ - public function install(): void { - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order` ( - `order_id` int(11) NOT NULL, - `transaction_id` varchar(20) NOT NULL, - `transaction_status` varchar(20) NULL, - `payment_method` varchar(20) NULL, - `vault_id` varchar(50) NULL, - `vault_customer_id` varchar(50) NULL, - `environment` varchar(20) NULL, - `status` tinyint(1) NOT NULL, - PRIMARY KEY (`order_id`, `transaction_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_subscription` ( - `paypal_checkout_integration_subscription_id` int(11) NOT NULL AUTO_INCREMENT, - `subscription_id` int(11) NOT NULL, - `order_id` int(11) NOT NULL, - `next_payment` datetime NOT NULL, - `trial_end` datetime DEFAULT NULL, - `subscription_end` datetime DEFAULT NULL, - `currency_code` varchar(3) NOT NULL, - `total` decimal(15,4) NOT NULL, - `payment_code` varchar(128) NOT NULL, - `date_added` datetime NOT NULL, - `date_modified` datetime NOT NULL, - PRIMARY KEY (`paypal_checkout_integration_subscription_id`), - KEY (`order_id`), - KEY (`subscription_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_transaction` ( - `paypal_checkout_integration_transaction_id` int(11) NOT NULL AUTO_INCREMENT, - `order_id` int(11) NOT NULL, - `reference` varchar(255) NOT NULL, - `type` tinyint(1) NOT NULL, - `amount` decimal(15,4) NOT NULL, - `date_added` datetime NOT NULL, - PRIMARY KEY (`paypal_checkout_integration_transaction_id`), - KEY (`order_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;"); - - $this->load->model('setting/setting'); - - // Setting - $_config = new \Config(); - $_config->load('paypal'); - - $config_setting = $_config->get('paypal_setting'); - - $this->model_setting_setting->deleteSetting('paypal_version'); - - $this->model_setting_setting->editSetting($config_setting['version']); - - // Events - $this->load->model('setting/event'); - - $this->model_setting_event->addEvent('paypal_order_info', 'admin/view/sale/order_info/before', 'extension/payment/paypal/order_info_before', 1, 0); - $this->model_setting_event->addEvent('paypal_header', 'catalog/controller/common/header/before', 'extension/payment/paypal/header_before', 1, 0); - $this->model_setting_event->addEvent('paypal_extension_get_extensions', 'paypal_extension_extensions', 'catalog/model/setting/extension/getExtensions/after', 'extension/payment/paypal/extension_get_extensions_after', 1, 0); - $this->model_setting_event->addEvent('paypal_order_delete_order', 'catalog/model/checkout/order/deleteOrder/before', 'extension/payment/paypal/order_delete_order_before', 1, 0); + + public function install() { + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token` (`customer_id` INT(11) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `main_token_status` TINYINT(1) NOT NULL, PRIMARY KEY (`customer_id`, `payment_method`, `vault_id`), KEY `vault_customer_id` (`vault_customer_id`), KEY `main_token_status` (`main_token_status`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order` (`order_id` INT(11) NOT NULL, `paypal_order_id` VARCHAR(20) NOT NULL, `transaction_id` VARCHAR(20) NOT NULL, `transaction_status` VARCHAR(20) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `total` DECIMAL(15,2) NOT NULL, `currency_code` VARCHAR(3) NOT NULL, `environment` VARCHAR(20) NOT NULL, `tracking_number` VARCHAR(64) NOT NULL, `carrier_name` VARCHAR(64) NOT NULL, PRIMARY KEY (`order_id`), KEY `paypal_order_id` (`paypal_order_id`), KEY `transaction_id` (`transaction_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` (`paypal_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT, `order_id` INT(11) NOT NULL, `order_recurring_id` INT(11) NOT NULL, `date_added` DATETIME NOT NULL, `date_modified` DATETIME NOT NULL, `next_payment` DATETIME NOT NULL, `trial_end` DATETIME DEFAULT NULL, `subscription_end` DATETIME DEFAULT NULL, `currency_code` CHAR(3) NOT NULL, `total` DECIMAL(10, 2) NOT NULL, PRIMARY KEY (`paypal_order_recurring_id`), KEY (`order_id`), KEY (`order_recurring_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); } - - /** - * Uninstall - * - * @return void - */ - public function uninstall(): void { - // Events - $this->load->model('setting/event'); - - $this->model_setting_event->deleteEventByCode('paypal_order_info'); - $this->model_setting_event->deleteEventByCode('paypal_header'); - $this->model_setting_event->deleteEventByCode('paypal_extension_get_extensions'); - $this->model_setting_event->deleteEventByCode('paypal_order_delete_order'); - $this->model_setting_event->deleteEventByCode('paypal_version'); + + public function uninstall() { + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring`"); + } + + public function update() { + if ($this->config->get('paypal_version') < '3.0.0') { + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring`"); + + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token` (`customer_id` INT(11) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `main_token_status` TINYINT(1) NOT NULL, PRIMARY KEY (`customer_id`, `payment_method`, `vault_id`), KEY `vault_customer_id` (`vault_customer_id`), KEY `main_token_status` (`main_token_status`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order` (`order_id` INT(11) NOT NULL, `paypal_order_id` VARCHAR(20) NOT NULL, `transaction_id` VARCHAR(20) NOT NULL, `transaction_status` VARCHAR(20) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `total` DECIMAL(15,2) NOT NULL, `currency_code` VARCHAR(3) NOT NULL, `environment` VARCHAR(20) NOT NULL, `tracking_number` VARCHAR(64) NOT NULL, `carrier_name` VARCHAR(64) NOT NULL, PRIMARY KEY (`order_id`), KEY `paypal_order_id` (`paypal_order_id`), KEY `transaction_id` (`transaction_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` (`paypal_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT, `order_id` INT(11) NOT NULL, `order_recurring_id` INT(11) NOT NULL, `date_added` DATETIME NOT NULL, `date_modified` DATETIME NOT NULL, `next_payment` DATETIME NOT NULL, `trial_end` DATETIME DEFAULT NULL, `subscription_end` DATETIME DEFAULT NULL, `currency_code` CHAR(3) NOT NULL, `total` DECIMAL(10, 2) NOT NULL, PRIMARY KEY (`paypal_order_recurring_id`), KEY (`order_id`), KEY (`order_recurring_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + } elseif ($this->config->get('paypal_version') < '3.1.0') { + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `total` DECIMAL(15,2) NOT NULL AFTER `card_expiry`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `currency_code` VARCHAR(3) NOT NULL AFTER `total`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `tracking_number` VARCHAR(64) NOT NULL AFTER `environment`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `carrier_name` VARCHAR(64) NOT NULL AFTER `tracking_number`"); + } } } diff --git a/upload/admin/view/image/payment/paypal/icon-message-configurator.svg b/upload/admin/view/image/payment/paypal/icon-message-configurator.svg new file mode 100644 index 000000000..fb5826e54 --- /dev/null +++ b/upload/admin/view/image/payment/paypal/icon-message-configurator.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/upload/admin/view/image/payment/paypal/icon-message-setting.svg b/upload/admin/view/image/payment/paypal/icon-message-setting.svg new file mode 100644 index 000000000..aeb458c57 --- /dev/null +++ b/upload/admin/view/image/payment/paypal/icon-message-setting.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/upload/admin/view/javascript/paypal/paypal.js b/upload/admin/view/javascript/paypal/paypal.js index a5b86cb8d..35dc80a16 100644 --- a/upload/admin/view/javascript/paypal/paypal.js +++ b/upload/admin/view/javascript/paypal/paypal.js @@ -21,25 +21,20 @@ var PayPalAPI = (function () { } if (paypal_data['components'].includes('googlepay')) { - $('#googlepay_button_container').html(''); - $('#googlepay_button_container').addClass('paypal-spinner'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').html(''); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').addClass('paypal-spinner'); } if (paypal_data['components'].includes('applepay')) { - $('#applepay_button_container').html(''); - $('#applepay_button_container').addClass('paypal-spinner'); + $('#applepay_button_' + paypal_data['page_code'] + '_container').html(''); + $('#applepay_button_' + paypal_data['page_code'] + '_container').addClass('paypal-spinner'); } - if (paypal_data['components'].includes('hosted-fields')) { + if (paypal_data['components'].includes('card-fields')) { $('#paypal_card_container').find('iframe').remove(); $('#paypal_card_container').addClass('paypal-spinner'); } - - if (paypal_data['components'].includes('messages')) { - $('#paypal_message_' + paypal_data['page_code'] + '_container').html(''); - $('#paypal_message_' + paypal_data['page_code'] + '_container').addClass('paypal-spinner'); - } - + var src_data = {}; src_data['components'] = paypal_data['components'].join(','); @@ -108,12 +103,12 @@ var PayPalAPI = (function () { env: paypal_data['environment'], locale: paypal_data['locale'], style: { - layout: ((paypal_data['page_code'] != 'checkout') ? 'horizontal' : 'vertical'), + layout: 'vertical', size: paypal_data['button_size'], color: paypal_data['button_color'], shape: paypal_data['button_shape'], label: paypal_data['button_label'], - tagline: ((paypal_data['page_code'] != 'checkout') ? paypal_data['button_tagline'] : 'false') + tagline: 'false' } }; @@ -128,26 +123,26 @@ var PayPalAPI = (function () { $('#paypal_button_' + paypal_data['page_code'] + '_container').removeClass('paypal-spinner'); } - - if (paypal_data['components'].includes('googlepay') && $('#googlepay_button').length && !$('#googlepay_button_container').html()) { + + if (paypal_data['components'].includes('googlepay') && $('#googlepay_button_' + paypal_data['page_code']).length && !$('#googlepay_button_' + paypal_data['page_code'] + '_container').html()) { if (google && PayPalSDK.Googlepay) { initGooglePaySDK().catch(console.log); } - $('#googlepay_button_container').removeClass('paypal-spinner'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').removeClass('paypal-spinner'); } - if (paypal_data['components'].includes('applepay') && $('#applepay_button').length && !$('#applepay_button_container').html()) { - $('#applepay_button').css('text-align', paypal_data['applepay_button_align']); + if (paypal_data['components'].includes('applepay') && $('#applepay_button_' + paypal_data['page_code']).length && !$('#applepay_button_' + paypal_data['page_code'] + '_container').html()) { + $('#applepay_button_' + paypal_data['page_code']).css('text-align', paypal_data['applepay_button_align']); var applepay_button_style = []; if (paypal_data['applepay_button_width']) { - $('#applepay_button_container').css('display', 'inline-block'); - $('#applepay_button_container').css('width', paypal_data['applepay_button_width']); + $('#applepay_button_' + paypal_data['page_code'] + '_container').css('display', 'inline-block'); + $('#applepay_button_' + paypal_data['page_code'] + '_container').css('width', paypal_data['applepay_button_width']); } else { - $('#applepay_button_container').css('display', 'block'); - $('#applepay_button_container').css('width', 'auto'); + $('#applepay_button_' + paypal_data['page_code'] + '_container').css('display', 'block'); + $('#applepay_button_' + paypal_data['page_code'] + '_container').css('width', 'auto'); } var applepay_button = document.createElement('apple-pay-button'); @@ -177,12 +172,12 @@ var PayPalAPI = (function () { applepay_button.setAttribute('style', applepay_button_style.join('; ')); - document.querySelector('#applepay_button_container').appendChild(applepay_button); + document.querySelector('#applepay_button_' + paypal_data['page_code'] + '_container').appendChild(applepay_button); - $('#applepay_button_container').removeClass('paypal-spinner'); + $('#applepay_button_' + paypal_data['page_code'] + '_container').removeClass('paypal-spinner'); } - if (paypal_data['components'].includes('hosted-fields') && $('#paypal_card').length) { + if (paypal_data['components'].includes('card-fields') && $('#paypal_card').length) { $('#paypal_card').css('text-align', paypal_data['card_align']); if (paypal_data['card_width']) { @@ -194,173 +189,72 @@ var PayPalAPI = (function () { } try { - // Check if card fields are eligible to render for the buyer's country. The card fields are not eligible in all countries where buyers are located. - if (PayPalSDK.HostedFields.isEligible() === true) { - var paypal_card_form = document.querySelector('#paypal_card_form'); - var paypal_button_submit = document.querySelector('#paypal_button_submit'); - - PayPalSDK.HostedFields.render({ - styles: { - 'input': { - 'color': '#282c37', - 'transition': 'color 0.1s', - 'line-height': '3' - }, - 'input.invalid': { - 'color': '#E53A40' - }, - ':-ms-input-placeholder': { - 'color': 'rgba(0,0,0,0.6)' - }, - ':-moz-placeholder': { - 'color': 'rgba(0,0,0,0.6)' - } - }, - fields: { - number: { - selector: '#card_number', - placeholder: '#### #### #### ####' - }, - cvv: { - selector: '#cvv', - placeholder: '###' - }, - expirationDate: { - selector: '#expiration_date', - placeholder: 'MM / YYYY' - } - }, - createOrder: function(data, actions) { - paypal_order_id = false; - - return paypal_order_id; + var paypal_card = PayPalSDK.CardFields({ + style: { + 'input': { + 'font-size': '1rem', + 'color': '#282c37', + 'transition': 'color 0.1s', + 'padding': '0.75rem 0.75rem', } - }).then(function(hostedFieldsInstance) { - hostedFieldsInstance.on('blur', function (event) { - console.log('CCF Event "blur", state=' + hostedFieldsInstance.getState() + ', event=' + event); - }); - - hostedFieldsInstance.on('focus', function (event) { - console.log('CCF Event "focus", state=' + hostedFieldsInstance.getState() + ', event=' + event); - }); - - hostedFieldsInstance.on('validityChange', function (event) { - console.log('CCF Event "validityChange", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - // Check if all fields are valid, then show submit button - var formValid = Object.keys(event.fields).every(function (key) { - return event.fields[key].isValid; - }); + }, + createOrder: function() { + paypal_order_id = false; + + return paypal_order_id; + }, + inputEvents: { + onChange: function(data) { + console.log('CCF Event "change", state=' + paypal_card.getState() + ', event=' + data); + + $('#paypal_card_form').removeClass().addClass('well'); + $('#paypal_card_form').removeAttr(); + + if (data.cards.length === 1) { + $('#paypal_card_form').addClass(data.cards[0].type); + $('#paypal_card_form').attr('card_type', data.cards[0].type); + $('#paypal_card_form').attr('card_nice_type', data.cards[0].niceType); + } - if (formValid) { - $('#paypal_button_submit').addClass('show-button'); + if (data.isFormValid) { + $('#paypal_card_button').addClass('show-button'); } else { - $('#paypal_button_submit').removeClass('show-button'); + $('#paypal_card_button').removeClass('show-button'); } - }); - - hostedFieldsInstance.on('notEmpty', function (event) { - console.log('CCF Event "notEmpty", state=' + hostedFieldsInstance.getState() + ', event=' + event); - }); - - hostedFieldsInstance.on('empty', function (event) { - console.log('CCF Event "empty", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - $(paypal_card_form).removeClass().addClass('well'); - $('#card_image').removeClass(); - }); - - hostedFieldsInstance.on('cardTypeChange', function (event) { - console.log('CCF Event "cardTypeChange", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - $(paypal_card_form).removeClass().addClass('well'); - $('#card_image').removeClass(); - - // Change card bg depending on card type - if (event.cards.length === 1) { - $(paypal_card_form).addClass(event.cards[0].type); - $('#card_image').addClass(event.cards[0].type); - - // Change the CVV length for AmericanExpress cards - if (event.cards[0].code.size === 4) { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '####' - }); - } else { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '###' - }); - } - } else { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '###' - }); + }, + onFocus: function(data) { + console.log('CCF Event "focus", state=' + paypal_card.getState() + ', event=' + data); + }, + onBlur: function(data) { + console.log('CCF Event "blur", state=' + paypal_card.getState() + ', event=' + data); + }, + onInputSubmitRequest: function(data) { + console.log('CCF Event "input submit request", state=' + paypal_card.getState() + ', event=' + data); + + if (data.isFormValid) { + $('#paypal_card_button').addClass('show-button'); + } else { + $('#paypal_card_button').removeClass('show-button'); } - }); - }); + } + } + }); + + if (paypal_card.isEligible()) { + paypal_card.NameField().render('#card_holder_name'); + paypal_card.NumberField().render('#card_number'); + paypal_card.ExpiryField().render('#expiration_date'); + paypal_card.CVVField().render('#cvv'); } else { console.log('Not eligible for CCF'); } } catch (error) { console.error('PayPal Card failed during startup', error); } - + $('#paypal_card_container').removeClass('paypal-spinner'); } - - if (paypal_data['components'].includes('messages') && $('#paypal_message_' + paypal_data['page_code']).length) { - $('#paypal_message_' + paypal_data['page_code']).css('text-align', paypal_data['message_align']); - - if (paypal_data['message_width']) { - $('#paypal_message_' + paypal_data['page_code'] + '_container').css('display', 'inline-block'); - $('#paypal_message_' + paypal_data['page_code'] + '_container').css('width', paypal_data['message_width']); - } else { - $('#paypal_message_' + paypal_data['page_code'] + '_container').css('display', 'block'); - $('#paypal_message_' + paypal_data['page_code'] + '_container').css('width', 'auto'); - } - - var paypal_message = document.createElement('div'); - - paypal_message.setAttribute('data-pp-message', ''); - - if (paypal_data['page_code'] == 'home') { - paypal_message.setAttribute('data-pp-placement', 'home'); - } - - if (paypal_data['page_code'] == 'product') { - paypal_message.setAttribute('data-pp-placement', 'product'); - } - - if (paypal_data['page_code'] == 'cart') { - paypal_message.setAttribute('data-pp-placement', 'cart'); - } - - if (paypal_data['page_code'] == 'checkout') { - paypal_message.setAttribute('data-pp-placement', 'payment'); - } - - paypal_message.setAttribute('data-pp-amount', '33.00'); - paypal_message.setAttribute('data-pp-style-layout', paypal_data['message_layout']); - - if (paypal_data['message_layout'] == 'text') { - paypal_message.setAttribute('data-pp-style-text-color', paypal_data['message_text_color']); - paypal_message.setAttribute('data-pp-style-text-size', paypal_data['message_text_size']); - } else { - paypal_message.setAttribute('data-pp-style-color', paypal_data['message_flex_color']); - paypal_message.setAttribute('data-pp-style-ratio', paypal_data['message_flex_ratio']); - } - - document.querySelector('#paypal_message_' + paypal_data['page_code'] + '_container').appendChild(paypal_message); - - $('#paypal_message_' + paypal_data['page_code'] + '_container').removeClass('paypal-spinner'); - } - + if (paypal_callback && typeof paypal_callback == 'function') { paypal_callback(); } @@ -375,7 +269,7 @@ var PayPalAPI = (function () { paymentsClient.isReadyToPay({allowedPaymentMethods, apiVersion, apiVersionMinor}).then(function(response) { if (response.result) { - $('#googlepay_button').css('text-align', paypal_data['googlepay_button_align']); + $('#googlepay_button_' + paypal_data['page_code']).css('text-align', paypal_data['googlepay_button_align']); var googlepay_button_style = []; @@ -393,14 +287,14 @@ var PayPalAPI = (function () { googlepay_button_style.push('aspect-ratio: 7.5'); - $('#googlepay_button_container').attr('style', googlepay_button_style.join('; ')); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').attr('style', googlepay_button_style.join('; ')); if (paypal_data['googlepay_button_shape'] == 'pill') { - $('#googlepay_button_container').removeClass('shape-rect'); - $('#googlepay_button_container').addClass('shape-pill'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').removeClass('shape-rect'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').addClass('shape-pill'); } else { - $('#googlepay_button_container').removeClass('shape-pill'); - $('#googlepay_button_container').addClass('shape-rect'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').removeClass('shape-pill'); + $('#googlepay_button_' + paypal_data['page_code'] + '_container').addClass('shape-rect'); } const googlepay_button = paymentsClient.createButton({ @@ -411,13 +305,13 @@ var PayPalAPI = (function () { onClick: function() {} }); - document.querySelector('#googlepay_button_container').appendChild(googlepay_button); + document.querySelector('#googlepay_button_' + paypal_data['page_code'] + '_container').appendChild(googlepay_button); } }).catch(function(error) { console.log(error); }); }; - + var init = function(data, callback = '') { paypal_data = data; paypal_callback = callback; diff --git a/upload/admin/view/stylesheet/paypal/card.css b/upload/admin/view/stylesheet/paypal/card.css index 2e30a9336..10862f8ae 100644 --- a/upload/admin/view/stylesheet/paypal/card.css +++ b/upload/admin/view/stylesheet/paypal/card.css @@ -1,38 +1,61 @@ #paypal_card_form { color: #717171; - text-align: center; + text-align: left; transition: all 600ms cubic-bezier(0.2, 1.3, 0.7, 1); -webkit-animation: cardIntro 500ms cubic-bezier(0.2, 1.3, 0.7, 1); animation: cardIntro 500ms cubic-bezier(0.2, 1.3, 0.7, 1); z-index: 1; } -#paypal_card_form.visa { - color: #fff; - background-color: #0D4AA2; -} -#paypal_card_form.master-card { - color: #fff; - background-color: #363636; - background: linear-gradient(115deg, #d82332, #d82332 50%, #f1ad3d 50%, #f1ad3d); -} -#paypal_card_form.maestro { - color: #fff; - background-color: #363636; - background: linear-gradient(115deg, #009ddd, #009ddd 50%, #ed1c2e 50%, #ed1c2e); -} #paypal_card_form.american-express { - color: #fff; + color: #FFFFFF; background-color: #007CC3; } +#paypal_card_form.diners-club { + color: #FFFFFF; + background-color: #0079BE; +} #paypal_card_form.discover { - color: #fff; + color: #FFFFFF; background-color: #ff6000; background: linear-gradient(#d14310, #f7961e); } -#paypal_card_form.unionpay, #paypal_card_form.jcb, #paypal_card_form.diners-club { - color: #fff; +#paypal_card_form.jcb { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(90deg, #005182, #005182 33%, #BE1833 33% 67%, #00933F 67%, #00933F); +} +#paypal_card_form.mastercard { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(115deg, #D82332, #D82332 50%, #F1AD3D 50%, #F1AD3D); +} +#paypal_card_form.maestro { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(115deg, #009DDD, #009DDD 50%, #ED1C2E 50%, #ED1C2E); +} +#paypal_card_form.unionpay { + color: #FFFFFF; background-color: #363636; + background: linear-gradient(100deg, #D10429, #D10429 33%, #022E64 33% 67%, #076F74 67%, #076F74); +} +#paypal_card_form.visa { + color: #FFFFFF; + background-color: #0D4AA2; +} +#paypal_card_form.elo { + color: #FFFFFF; + background-color: #000000; } +#paypal_card_form.hiper { + color: #FFFFFF; + background-color: #F37421; +} +#paypal_card_form.hipercard { + color: #FFFFFF; + background-color: #BA1319 +} +#paypal_card_form .card-info-holder-name, #paypal_card_form .card-info-number, #paypal_card_form .card-info-date-cvv { position: relative; @@ -48,65 +71,23 @@ float: right; margin-bottom: 0.5em; } +#paypal_card_form .card-info-holder-name, #paypal_card_form .card-info-number, #paypal_card_form .card-info-date, #paypal_card_form .card-info-cvv { - transition: -webkit-transform 0.3s; - transition: transform 0.3s; - transition: transform 0.3s, -webkit-transform 0.3s; -} -#paypal_card_form .card-label { - display: block; - margin-bottom: 0.5em; - text-transform: uppercase; + transition: -webkit-transform 0.3s; + transition: transform 0.3s; + transition: transform 0.3s, -webkit-transform 0.3s; } -#paypal_card_form .card-input-container { +#paypal_card_form .card-button { position: relative; - height: 2.75em; - padding: 5px 10px; - margin-bottom: 1em; - background: rgba(255, 255, 255, 0.86); - border: 1px solid #eee; - border-radius: 2px; -} -#paypal_card_form #card_image { - position: absolute; - top: 0px; - right: 2px; - width: 44px; - height: 28px; - background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/346994/card_sprite.png); - background-size: 86px 458px; - border-radius: 4px; - background-position: -100px 0; - background-repeat: no-repeat; -} -#paypal_card_form #card_image.visa { - background-position: 0 -398px; -} -#paypal_card_form #card_image.master-card { - background-position: 0 -281px; -} -#paypal_card_form #card_image.american-express { - background-position: 0 -370px; -} -#paypal_card_form #card_image.discover { - background-position: 0 -163px; -} -#paypal_card_form #card_image.maestro { - background-position: 0 -251px; -} -#paypal_card_form #card_image.jcb { - background-position: 0 -221px; -} -#paypal_card_form #card_image.diners-club { - background-position: 0 -133px; -} -#paypal_card_form #paypal_button_submit { + padding: 0rem 0.6rem; +} +#paypal_card_form .paypal-card-button { width: 100%; - padding: 1em 1em; - color: #fff; - background: #282c37; + padding: 16px 16px; + color: #FFFFFF; + background: #282C37; font-size: 15px; box-shadow: none; -moz-box-shadow: none; @@ -117,14 +98,21 @@ outline: 0; -webkit-appearance: none; } -#paypal_card_form #paypal_button_submit:hover { +#paypal_card_form .paypal-card-button:hover { background: #535b72; } -#paypal_card_form #paypal_button_submit:active { +#paypal_card_form.elo .paypal-card-button { + color: #000000; + background: #FFFFFF; +} +#paypal_card_form.elo .paypal-card-button:hover { + background: #F5F5F5; +} +#paypal_card_form .paypal-card-button:active { -webkit-animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); } -#paypal_card_form #paypal_button_submit.show-button { +#paypal_card_form .paypal-card-button.show-button { opacity: 1; cursor: pointer; } \ No newline at end of file diff --git a/upload/admin/view/stylesheet/paypal/paypal.css b/upload/admin/view/stylesheet/paypal/paypal.css index 3f874bcae..9d1016873 100644 --- a/upload/admin/view/stylesheet/paypal/paypal.css +++ b/upload/admin/view/stylesheet/paypal/paypal.css @@ -357,9 +357,13 @@ width: 33px; background-image: url('../../image/payment/paypal/icon-card.svg'); } -.payment-paypal .panel-default .tab .tab-icon-message { +.payment-paypal .panel-default .tab .tab-icon-message-setting { width: 37px; - background-image: url('../../image/payment/paypal/icon-message.svg'); + background-image: url('../../image/payment/paypal/icon-message-setting.svg'); +} +.payment-paypal .panel-default .tab .tab-icon-message-configurator { + width: 37px; + background-image: url('../../image/payment/paypal/icon-message-configurator.svg'); } .payment-paypal .panel-default .tab .tab-icon-order-status { width: 28px; @@ -656,6 +660,42 @@ background-size: contain; background-repeat: no-repeat; } +.payment-paypal .panel-default #messaging-configurator * { + font-size: 13px; + line-height: 1.4; + -webkit-box-sizing: revert; + -moz-box-sizing: revert; + box-sizing: revert; +} +.payment-paypal .panel-default #messaging-configurator > div { + margin: 0 !important; + justify-content: flex-start !important; +} +.payment-paypal .panel-default #configurator-eligibleContainer { + width: 100% !important; + max-width: 110rem !important; + padding: 0 !important; +} +.payment-paypal .panel-default #messaging-configurator #configurator-eligibleContainer .headerOverride { + font-size: 15px; + font-weight: 700; + color: #000000; +} +.payment-paypal .panel-default #messaging-configurator #configurator-eligibleContainer .buttonOverride { + display: none; +} +.payment-paypal .panel-default #messaging-configurator #configurator-eligibleContainer input { + position: absolute; +} +.payment-paypal .panel-default #messaging-configurator #configurator-controlPanelContainer { + margin-right: 50px; +} +.payment-paypal .panel-default #messaging-configurator #configurator-controlPanelContainer [accordionname] button:not([id^="dropdownMenuButton"]) { + padding: 8px 16px 16px 16px; +} +.payment-paypal .panel-default #messaging-configurator #configurator-previewSectionContainer > div + div { + height: auto; +} @media (max-width: 767px) { .payment-paypal .panel-default .section-cart .table-cart .table-row .table-col-product-image, .payment-paypal .panel-default .section-cart .table-cart .table-row .table-col-product-model, @@ -764,9 +804,6 @@ width: 100% !important; } } -.payment-paypal .panel-default .paypal-message { - position: relative; -} .payment-paypal .panel-default .paypal-spinner { position: relative; min-height: 20px; @@ -816,7 +853,7 @@ .payment-paypal .panel-auth .section-connect .welcome { font-size: 18px; color: #1D1D1D; - margin-bottom: 37px; + margin-bottom: 20px; } .payment-paypal .panel-auth .section-connect .checkout-express { font-size: 13px; @@ -827,7 +864,7 @@ display: inline-block; vertical-align: top; font-family: 'Open Sans', sans-serif; - margin-bottom: 37px; + margin: 20px 0px 37px 0px; } .payment-paypal .panel-auth .section-connect .button-connect-ppcp::before { display: none; @@ -845,6 +882,10 @@ .payment-paypal .panel-auth .section-connect .button-connect-express-checkout::before { display: none; } +.payment-paypal .panel-auth .section-connect .button-connect { + display: inline-block; + margin: 10px 0px 37px 0px; +} .payment-paypal .panel-auth .section-connect .control-label { font-size: 13px; color: #787878; @@ -867,6 +908,11 @@ .payment-paypal .panel-dashboard .col { padding: 0px 7px; } +@media (min-width: 1200px) { + .payment-paypal .panel-dashboard .col-tab { + width: 20%; + } +} .payment-paypal .panel-dashboard .paypal-sale { padding: 11px 0px; } @@ -890,7 +936,7 @@ .payment-paypal .panel-dashboard .tab { position: relative; display: block; - padding: 37px 7px 30px 7px; + padding: 37px 10px 30px 10px; text-align: center; background: #FFFFFF; box-shadow: 0px 2px 6px #00000029; diff --git a/upload/admin/view/template/extension/payment/paypal/applepay_button.twig b/upload/admin/view/template/extension/payment/paypal/applepay_button.twig index 5aa1e69df..2fdd57da1 100644 --- a/upload/admin/view/template/extension/payment/paypal/applepay_button.twig +++ b/upload/admin/view/template/extension/payment/paypal/applepay_button.twig @@ -1,185 +1,300 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
-
-
-
-
{{ text_checkout }}
-
-
{{ text_step_payment_method }}
-
-
-
{{ text_step_confirm_order }}
-
-
-
-
-
-
{{ text_cart_sub_total }}
-
{{ text_cart_product_total_value }}
-
-
-
{{ text_cart_total }}
-
{{ text_cart_product_total_value }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ text_applepay_button_settings }} -
-
-
- - {% set setting_applepay_button = setting.applepay_button %} - -
-
-
- {% if text_applepay_alert %} -
-

{{ text_applepay_alert }}

-
-
-

{{ text_applepay_step_1 }}

-
- -
- -
-
-
-
-

{{ text_applepay_step_2 }}

-
- {% endif %} -
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
-
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+ +
+
+ {% for applepay_button in setting['applepay_button'] %} +
+
+
+ {% if (applepay_button['page_code'] == 'checkout') %} +
+
{{ text_checkout }}
+
+
{{ text_step_payment_method }}
+
+
+
{{ text_step_confirm_order }}
+
+
+
+
+
+
{{ text_cart_sub_total }}
+
{{ text_cart_product_total_value }}
+
+
+
{{ text_cart_total }}
+
{{ text_cart_product_total_value }}
+
+
+
+
+
+
+
+
+ {% endif %} + {% if (applepay_button['page_code'] == 'cart') %} +
+
{{ text_cart }}
+
+
+
{{ text_cart_product_image }}
+
{{ text_cart_product_name }}
+
{{ text_cart_product_model }}
+
{{ text_cart_product_quantity }}
+
{{ text_cart_product_price }}
+
{{ text_cart_product_total }}
+
+
+
+
{{ text_cart_product_name_value }}
+
{{ text_cart_product_model_value }}
+
{{ text_cart_product_quantity_value }}
+
{{ text_cart_product_price_value }}
+
{{ text_cart_product_total_value }}
+
+
+
+
{{ text_step_coupon }}
+
+
+
{{ text_step_shipping }}
+
+
+
+
+
+
{{ text_cart_sub_total }}
+
{{ text_cart_product_total_value }}
+
+
+
{{ text_cart_total }}
+
{{ text_cart_product_total_value }}
+
+
+
+
+
+
+ +
+
+
+
+
+
+ {% endif %} + {% if (applepay_button['page_code'] == 'product') %} +
+
+
+
+
+
+
{{ text_product_name }}
+
{{ text_product_price }}
+
{{ text_product_manufacturer }}
+
{{ text_product_model }}
+
{{ text_product_stock }}
+ +
+
+
+
+
+
+ {% endif %} +
+
+
+
+
+ {{ text_applepay_button_settings }} +
+
+
+ + + +
+
+
+ {% if text_applepay_alert %} +
+

{{ text_applepay_alert }}

+
+
+

{{ text_applepay_step_1 }}

+
+ +
+ +
+
+
+
+

{{ text_applepay_step_2 }}

+
+ {% endif %} + {% if (applepay_button['page_code'] != 'checkout') %} +
+
+
+ + +
+
+
+
+ + +
+
+
+ {% endif %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+ {% endfor %} +
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/auth.twig b/upload/admin/view/template/extension/payment/paypal/auth.twig index 345fda692..736d39fc5 100644 --- a/upload/admin/view/template/extension/payment/paypal/auth.twig +++ b/upload/admin/view/template/extension/payment/paypal/auth.twig @@ -1,74 +1,166 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- -
{{ text_welcome }}
- {{ button_connect }} -
{{ text_checkout_express }}
-
{{ text_support }}
-
-
-
- - -
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ +
{{ text_welcome }}
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ {{ button_connect }} +
{{ text_checkout_express }}
+
+
+
+ + +
+
+ + +
+
+ +
+ + + + +
+
+
+
+ +
+
+
+
{{ text_support }}
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/card.twig b/upload/admin/view/template/extension/payment/paypal/card.twig index be3a91e92..06ebc1526 100644 --- a/upload/admin/view/template/extension/payment/paypal/card.twig +++ b/upload/admin/view/template/extension/payment/paypal/card.twig @@ -1,165 +1,173 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
-
-
-
-
{{ text_checkout }}
-
-
{{ text_step_payment_method }}
-
-
-
{{ text_step_confirm_order }}
-
-
-
-
-
-
{{ text_cart_sub_total }}
-
{{ text_cart_product_total_value }}
-
-
-
{{ text_cart_total }}
-
{{ text_cart_product_total_value }}
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
- {{ text_card_settings }} -
-
-
- - {% set setting_card = setting.card %} - -
-
-
-
- - -
-
- - -
-
- -
- - -
-
-
- -
-
- -

{{ help_card_secure_scenario }}

-
- {% for card_secure_scenario in setting.card_secure_scenario %} -
- - -
- {% endfor %} -
-
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+
+
+
+
{{ text_checkout }}
+
+
{{ text_step_payment_method }}
+
+
+
{{ text_step_confirm_order }}
+
+
+
+
+
+
{{ text_cart_sub_total }}
+
{{ text_cart_product_total_value }}
+
+
+
{{ text_cart_total }}
+
{{ text_cart_product_total_value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ {{ text_card_settings }} +
+
+
+ + + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +

{{ help_card_secure_scenario }}

+
+ {% for card_secure_scenario in setting['card_secure_scenario'] %} +
+ + +
+ {% endfor %} +
+
+
+
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/contact.twig b/upload/admin/view/template/extension/payment/paypal/contact.twig index 7faa7ad16..d5d196b17 100644 --- a/upload/admin/view/template/extension/payment/paypal/contact.twig +++ b/upload/admin/view/template/extension/payment/paypal/contact.twig @@ -1,154 +1,157 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
-
-
- {{ text_contact_business }} -
-
{% set setting_contact = setting.contact %} - - - - - - -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
- - -
-
-
- - -
-
- {{ text_contact_product }} -
- - -
-
- -
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+
+
+ {{ text_contact_business }} +
+
+ + + + + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ {{ text_contact_product }} +
+ + +
+
+ +
+
+
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/dashboard.twig b/upload/admin/view/template/extension/payment/paypal/dashboard.twig index 15923fdb9..b0eb44aac 100644 --- a/upload/admin/view/template/extension/payment/paypal/dashboard.twig +++ b/upload/admin/view/template/extension/payment/paypal/dashboard.twig @@ -1,117 +1,156 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
-
-
-
- {{ text_paypal_sales }}: {{ paypal_sale_total }} -
-
-
-
- - - -
-
-
- -
-
-
-
-

{{ text_panel_statistic }}

-
-
-
- -
{{ text_statistic_title }}
-
{{ text_statistic_description }}
-
-
-
-
-
-
-
-
- - -
-

{{ text_panel_sale_analytics }}

-
-
-
-
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+
+
+
+ {{ text_paypal_sales }}: {{ paypal_sale_total }} +
+
+
+
+ + + +
+
+
+ +
+
+
+
+

{{ text_panel_statistic }}

+
+
+
+ +
{{ text_statistic_title }}
+
{{ text_statistic_description }}
+
+
+
+
+
+
+
+
+ + +
+

{{ text_panel_sale_analytics }}

+
+
+
+
+
+
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/general.twig b/upload/admin/view/template/extension/payment/paypal/general.twig index 4714eaeeb..be77c2ea1 100644 --- a/upload/admin/view/template/extension/payment/paypal/general.twig +++ b/upload/admin/view/template/extension/payment/paypal/general.twig @@ -1,200 +1,218 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
- -
- -
-
- -

{{ text_connect }}

-
-
-
-
- -
- - -
-
-
-
-
- -
- {% set setting_general = setting.general %} - -
-
-
-
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- - -
-
-
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+ +
+ +
+
+ +

{{ text_connect }}

+
+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ +
+ + +
+
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+ + + + +
+
+
+
+
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/googlepay_button.twig b/upload/admin/view/template/extension/payment/paypal/googlepay_button.twig index 6bb19846f..823539ac0 100644 --- a/upload/admin/view/template/extension/payment/paypal/googlepay_button.twig +++ b/upload/admin/view/template/extension/payment/paypal/googlepay_button.twig @@ -1,166 +1,285 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
-
-
-
-
{{ text_checkout }}
-
-
{{ text_step_payment_method }}
-
-
-
{{ text_step_confirm_order }}
-
-
-
-
-
-
{{ text_cart_sub_total }}
-
{{ text_cart_product_total_value }}
-
-
-
{{ text_cart_total }}
-
{{ text_cart_product_total_value }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ text_googlepay_button_settings }} -
-
-
- - {% set setting_googleplay_button = setting.googlepay_button %} - -
-
-
-
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
-
-
-
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+ +
+
+ {% for googlepay_button in setting['googlepay_button'] %} +
+
+
+ {% if (googlepay_button['page_code'] == 'checkout') %} +
+
{{ text_checkout }}
+
+
{{ text_step_payment_method }}
+
+
+
{{ text_step_confirm_order }}
+
+
+
+
+
+
{{ text_cart_sub_total }}
+
{{ text_cart_product_total_value }}
+
+
+
{{ text_cart_total }}
+
{{ text_cart_product_total_value }}
+
+
+
+
+
+
+
+
+ {% endif %} + {% if (googlepay_button['page_code'] == 'cart') %} +
+
{{ text_cart }}
+
+
+
{{ text_cart_product_image }}
+
{{ text_cart_product_name }}
+
{{ text_cart_product_model }}
+
{{ text_cart_product_quantity }}
+
{{ text_cart_product_price }}
+
{{ text_cart_product_total }}
+
+
+
+
{{ text_cart_product_name_value }}
+
{{ text_cart_product_model_value }}
+
{{ text_cart_product_quantity_value }}
+
{{ text_cart_product_price_value }}
+
{{ text_cart_product_total_value }}
+
+
+
+
{{ text_step_coupon }}
+
+
+
{{ text_step_shipping }}
+
+
+
+
+
+
{{ text_cart_sub_total }}
+
{{ text_cart_product_total_value }}
+
+
+
{{ text_cart_total }}
+
{{ text_cart_product_total_value }}
+
+
+
+
+
+
+ +
+
+
+
+
+
+ {% endif %} + {% if (googlepay_button['page_code'] == 'product') %} +
+
+
+
+
+
+
{{ text_product_name }}
+
{{ text_product_price }}
+
{{ text_product_manufacturer }}
+
{{ text_product_model }}
+
{{ text_product_stock }}
+ +
+
+
+
+
+
+ {% endif %} +
+
+
+
+
+ {{ text_googlepay_button_settings }} +
+
+
+ + + +
+
+
+ {% if (googlepay_button['page_code'] != 'checkout') %} +
+
+
+ + +
+
+
+
+ + +
+
+
+ {% endif %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+ {% endfor %} +
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/message_configurator.twig b/upload/admin/view/template/extension/payment/paypal/message_configurator.twig new file mode 100644 index 000000000..0a5442f95 --- /dev/null +++ b/upload/admin/view/template/extension/payment/paypal/message_configurator.twig @@ -0,0 +1,193 @@ +{{ header }}{{ column_left }} +
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} + +
+
+ +{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/message_setting.twig b/upload/admin/view/template/extension/payment/paypal/message_setting.twig new file mode 100644 index 000000000..fe58281a9 --- /dev/null +++ b/upload/admin/view/template/extension/payment/paypal/message_setting.twig @@ -0,0 +1,145 @@ +{{ header }}{{ column_left }} +
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+ +
+
+ {% for message in setting['message'] %} + {% if (message['page_code'] != 'checkout') %} +
+
+
+
+ {{ text_message_settings }} +
+
+ {% if text_message_alert %} + {#
+

{{ text_message_alert }}

+
+
+

{{ text_message_footnote }}

+
#} + {% endif %} +
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ {% endif %} + {% endfor %} +
+
+
+
+
+
+
+ +{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/order.twig b/upload/admin/view/template/extension/payment/paypal/order.twig index 2e5e34ccf..3c58ed9ca 100644 --- a/upload/admin/view/template/extension/payment/paypal/order.twig +++ b/upload/admin/view/template/extension/payment/paypal/order.twig @@ -1,155 +1,358 @@ -
{{ text_transaction_id }}: {{ transaction_id }}
-
-
{{ attribute(_context, 'text_transaction_' ~ transaction_status) }}
-
-{% if transaction_status == 'created' %} - - - -{% endif %} -{% if transaction_status == 'completed' %} - -{% endif %} +
+
+ + + + + + + + + + + + + + + + {% if ((transaction_status == 'created') or (transaction_status == 'completed') or (transaction_status == 'partially_captured') or (transaction_status == 'partially_refunded')) %} + + + + + {% endif %} + +
{{ text_payment_information }}
{{ text_transaction_id }} + {{ transaction_id }} + + +
{{ text_transaction_description }}{{ attribute(_context, 'text_transaction_' ~ transaction_status) }}
{{ text_transaction_action }} + {% if ((transaction_status == 'created') or (transaction_status == 'partially_captured')) %} +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ {% endif %} + {% if ((transaction_status == 'completed') or (transaction_status == 'partially_refunded')) %} +
+
+ +
+
+ +
+
+ {% endif %} +
+
+ {% if (transaction_status == 'completed') %} +
+ + + + + + + + + + + + + + + + + + + + +
{{ text_tracker_information }}
{{ text_tracking_number }} + {% if tracking_number %} + {{ tracking_number }} + + {% else %} + + {% endif %} +
{{ text_carrier_name }} + {% if carrier_name %} + {{ carrier_name }} + + {% else %} + + {% endif %} +
{{ text_tracker_action }} + {% if tracking_number %} + + {% else %} + + {% endif %} +
+
+ {% endif %} +
\ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/order_status.twig b/upload/admin/view/template/extension/payment/paypal/order_status.twig index dc0ab8074..2fda3d8c3 100644 --- a/upload/admin/view/template/extension/payment/paypal/order_status.twig +++ b/upload/admin/view/template/extension/payment/paypal/order_status.twig @@ -1,75 +1,78 @@ {{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }}
- {% endif %} - {% if text_version %} -
{{ text_version }}
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
- {{ text_tab_dashboard }} - -
-
- {% for column_paypal_order_status in setting.order_status|batch(setting.order_status|length / 2|round(1, 'ceil')) %} -
- {% for paypal_order_status in column_paypal_order_status %} -
- - -
- {% endfor %} -
- {% endfor %} -
-
-
-
-
-
+
+ +
+ {% if error_warning %} +
{{ error_warning }}
+ {% endif %} + {% if text_version %} +
{{ text_version }}
+ {% endif %} +
+
+

{{ text_edit }}

+
+
+
+ {{ text_tab_dashboard }} + +
+
+ {% for column_paypal_order_status in setting['order_status']|batch(setting['order_status']|length / 2|round(1, 'ceil')) %} +
+ {% for paypal_order_status in column_paypal_order_status %} +
+ + +
+ {% endfor %} +
+ {% endfor %} +
+
+
+
+
+
{{ footer }} \ No newline at end of file diff --git a/upload/admin/view/template/extension/payment/paypal/recurring.twig b/upload/admin/view/template/extension/payment/paypal/recurring.twig new file mode 100644 index 000000000..d3db49970 --- /dev/null +++ b/upload/admin/view/template/extension/payment/paypal/recurring.twig @@ -0,0 +1,81 @@ +
+ {% if ((recurring_status == '2') or (recurring_status == '3')) %} + + {% else %} + + {% endif %} +
+
+ \ No newline at end of file diff --git a/upload/catalog/controller/extension/payment/paypal.php b/upload/catalog/controller/extension/payment/paypal.php index 5077615b1..315d2c848 100644 --- a/upload/catalog/controller/extension/payment/paypal.php +++ b/upload/catalog/controller/extension/payment/paypal.php @@ -1,537 +1,735 @@ - */ - private array $error = []; - - /** - * Index - * - * @return string - */ - public function index(): string { + private $error = array(); + + public function __construct($registry) { + parent::__construct($registry); + + if (version_compare(phpversion(), '7.1', '>=')) { + ini_set('precision', 14); + ini_set('serialize_precision', 14); + } + + if (empty($this->config->get('paypal_version')) || (!empty($this->config->get('paypal_version')) && ($this->config->get('paypal_version') < '3.1.0'))) { + $this->update(); + } + } + + public function index() { $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - - if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && !$this->webhook() && !$this->cron() && $agree_status) { + + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && !$this->callback() && !$this->webhook() && !$this->cron() && $agree_status) { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); $data['environment'] = $this->config->get('payment_paypal_environment'); $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; + $data['vault_status'] = $setting['general']['vault_status']; $data['checkout_mode'] = $setting['general']['checkout_mode']; $data['transaction_method'] = $setting['general']['transaction_method']; - + $data['button_status'] = $setting['button']['checkout']['status']; - $data['googlepay_button_status'] = $setting['googlepay_button']['status']; - $data['applepay_button_status'] = $setting['applepay_button']['status']; + $data['googlepay_button_status'] = $setting['googlepay_button']['checkout']['status']; $data['card_status'] = $setting['card']['status']; + + if ($setting['applepay_button']['checkout']['status'] && $this->isApple()) { + $data['applepay_button_status'] = $setting['applepay_button']['checkout']['status']; + } else { + $data['applepay_button_status'] = false; + } - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + $data['logged'] = $this->customer->isLogged(); + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } return $this->load->view('extension/payment/paypal/paypal', $data); } - + return ''; } - - /** - * Modal - * - * @return void - */ - public function modal(): void { + + public function modal() { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); $data['environment'] = $this->config->get('payment_paypal_environment'); $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; + $data['vault_status'] = $setting['general']['vault_status']; $data['transaction_method'] = $setting['general']['transaction_method']; - + $data['button_status'] = $setting['button']['checkout']['status']; - $data['googlepay_button_status'] = $setting['googlepay_button']['status']; - $data['applepay_button_status'] = $setting['applepay_button']['status']; + $data['googlepay_button_status'] = $setting['googlepay_button']['checkout']['status']; $data['card_status'] = $setting['card']['status']; - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + if ($setting['applepay_button']['checkout']['status'] && $this->isApple()) { + $data['applepay_button_status'] = $setting['applepay_button']['checkout']['status']; + } else { + $data['applepay_button_status'] = false; + } + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } - + } + $data['error'] = $this->error; $this->response->setOutput($this->load->view('extension/payment/paypal/paypal_modal', $data)); } - - /** - * Get Data - * - * @return void - */ - public function getData(): void { + + public function getData() { $this->load->model('extension/payment/paypal'); - - $json = []; - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - - if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status && !empty($this->request->post['page_code'])) { + + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status && !empty($this->request->post['page_code'])) { $this->load->language('extension/payment/paypal'); - + $this->load->model('localisation/country'); $this->load->model('checkout/order'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - - $json['page_code'] = $this->request->post['page_code']; - $json['client_id'] = $this->config->get('payment_paypal_client_id'); - $json['secret'] = $this->config->get('payment_paypal_secret'); - $json['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); - $json['environment'] = $this->config->get('payment_paypal_environment'); - $json['partner_id'] = $setting['partner'][$json['environment']]['partner_id']; - $json['partner_attribution_id'] = $setting['partner'][$json['environment']]['partner_attribution_id']; - $json['transaction_method'] = $setting['general']['transaction_method']; - + + $data['page_code'] = $this->request->post['page_code']; + $data['client_id'] = $this->config->get('payment_paypal_client_id'); + $data['secret'] = $this->config->get('payment_paypal_secret'); + $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); + $data['environment'] = $this->config->get('payment_paypal_environment'); + $data['googlepay_environment'] = (($data['environment'] == 'production') ? 'PRODUCTION' : 'TEST'); + $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; + $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; + $data['vault_status'] = $setting['general']['vault_status']; + $data['transaction_method'] = $setting['general']['transaction_method']; + $country = $this->model_extension_payment_paypal->getCountryByCode($setting['general']['country_code']); - - $json['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; - - $json['currency_code'] = $this->session->data['currency']; - $json['currency_value'] = $this->currency->getValue($this->session->data['currency']); - - if (empty($setting['currency'][$json['currency_code']]['status'])) { - $json['currency_code'] = $setting['general']['currency_code']; - $json['currency_value'] = $setting['general']['currency_value']; + + $data['locale'] = preg_replace('/-(.+?)+/', '', $this->config->get('config_language')) . '_' . $country['iso_code_2']; + + $data['currency_code'] = $this->session->data['currency']; + $data['currency_value'] = $this->currency->getValue($this->session->data['currency']); + + if (empty($setting['currency'][$data['currency_code']]['status'])) { + $data['currency_code'] = $setting['general']['currency_code']; + $data['currency_value'] = $setting['general']['currency_value']; } - - $json['decimal_place'] = $setting['currency'][$json['currency_code']]['decimal_place']; - - $json['components'] = []; - - if ($this->request->post['page_code'] == 'home') { - if ($setting['message']['home']['status'] && ($json['currency_code'] == $setting['general']['currency_code'])) { - $json['components'][] = 'messages'; - $json['message_status'] = $setting['message']['home']['status']; - $json['message_insert_tag'] = html_entity_decode($setting['message']['home']['insert_tag']); - $json['message_insert_type'] = $setting['message']['home']['insert_type']; - $json['message_align'] = $setting['message']['home']['align']; - $json['message_size'] = $setting['message']['home']['size']; - $json['message_width'] = $setting['message_width'][$json['message_size']]; - $json['message_layout'] = $setting['message']['home']['layout']; - $json['message_text_color'] = $setting['message']['home']['text_color']; - $json['message_text_size'] = $setting['message']['home']['text_size']; - $json['message_flex_color'] = $setting['message']['home']['flex_color']; - $json['message_flex_ratio'] = $setting['message']['home']['flex_ratio']; - + + $data['decimal_place'] = $setting['currency'][$data['currency_code']]['decimal_place']; + + $data['components'] = array(); + + if ($this->request->post['page_code'] == 'home') { + if ($setting['message']['home']['status'] && !empty($setting['paylater_country'][$setting['general']['country_code']]) && ($data['currency_code'] == $setting['general']['currency_code'])) { + $data['components'][] = 'messages'; + $data['message_status'] = $setting['message']['home']['status']; + $data['message_insert_tag'] = html_entity_decode($setting['message']['home']['insert_tag']); + $data['message_insert_type'] = $setting['message']['home']['insert_type']; + $data['message_layout'] = $setting['message']['home']['layout']; + $data['message_logo_type'] = $setting['message']['home']['logo_type']; + $data['message_logo_position'] = $setting['message']['home']['logo_position']; + $data['message_text_color'] = $setting['message']['home']['text_color']; + $data['message_text_size'] = $setting['message']['home']['text_size']; + $data['message_flex_color'] = $setting['message']['home']['flex_color']; + $data['message_flex_ratio'] = $setting['message']['home']['flex_ratio']; + $item_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); - + $item_total += $product_price * $product['quantity']; } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } - - $json['message_amount'] = number_format($item_total * $json['currency_value'], $json['decimal_place'], '.', ''); + + $data['message_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); } } + + if (!empty($this->request->post['product'])) { + $this->request->post['product'] = $this->unserialize($this->request->post['product']); + } + + if (($this->request->post['page_code'] == 'product') && !empty($this->request->post['product']['product_id'])) { + $product = $this->request->post['product']; + $product_id = (int)$this->request->post['product']['product_id']; + $product_price = 0; + + if (isset($product['quantity'])) { + $quantity = (int)$product['quantity']; + } else { + $quantity = 1; + } - if (($this->request->post['page_code'] == 'product') && !empty($this->request->post['product_id'])) { - if ($setting['button']['product']['status']) { - $json['components'][] = 'buttons'; - $json['button_status'] = $setting['button']['product']['status']; - $json['button_insert_tag'] = html_entity_decode($setting['button']['product']['insert_tag']); - $json['button_insert_type'] = $setting['button']['product']['insert_type']; - $json['button_align'] = $setting['button']['product']['align']; - $json['button_size'] = $setting['button']['product']['size']; - $json['button_width'] = $setting['button_width'][$json['button_size']]; - $json['button_color'] = $setting['button']['product']['color']; - $json['button_shape'] = $setting['button']['product']['shape']; - $json['button_label'] = $setting['button']['product']['label']; - $json['button_tagline'] = $setting['button']['product']['tagline']; - } - - if ($setting['message']['product']['status'] && ($json['currency_code'] == $setting['general']['currency_code'])) { - $json['components'][] = 'messages'; - $json['message_status'] = $setting['message']['product']['status']; - $json['message_insert_tag'] = html_entity_decode($setting['message']['product']['insert_tag']); - $json['message_insert_type'] = $setting['message']['product']['insert_type']; - $json['message_align'] = $setting['message']['product']['align']; - $json['message_size'] = $setting['message']['product']['size']; - $json['message_width'] = $setting['message_width'][$json['message_size']]; - $json['message_layout'] = $setting['message']['product']['layout']; - $json['message_text_color'] = $setting['message']['product']['text_color']; - $json['message_text_size'] = $setting['message']['product']['text_size']; - $json['message_flex_color'] = $setting['message']['product']['flex_color']; - $json['message_flex_ratio'] = $setting['message']['product']['flex_ratio']; - - $product_id = (int)$this->request->post['product_id']; - - $this->load->model('catalog/product'); - - $product_info = $this->model_catalog_product->getProduct($product_id); - - if ($product_info) { - if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) { - if ((float)$product_info['special']) { - $product_price = $this->tax->calculate($product_info['special'], $product_info['tax_class_id'], true); - } else { - $product_price = $this->tax->calculate($product_info['price'], $product_info['tax_class_id'], true); - } + if (isset($product['option'])) { + $option = array_filter($product['option']); + } else { + $option = array(); + } + + $this->load->model('catalog/product'); - $json['message_amount'] = number_format($product_price * $json['currency_value'], $json['decimal_place'], '.', ''); + $product_info = $this->model_catalog_product->getProduct($product_id); + + if ($product_info && ($this->customer->isLogged() || !$this->config->get('config_customer_price'))) { + $option_price = 0; + + $product_options = $this->model_catalog_product->getProductOptions($product_id); + + foreach ($product_options as $product_option) { + if (isset($option[$product_option['product_option_id']])) { + if (($product_option['type'] == 'select') || ($product_option['type'] == 'radio')) { + foreach ($product_option['product_option_value'] as $product_option_value) { + if (!$product_option_value['subtract'] || ($product_option_value['quantity'] > 0)) { + if ((float)$product_option_value['price']) { + if ($option[$product_option['product_option_id']] == $product_option_value['product_option_value_id']) { + if ($product_option_value['price_prefix'] == '+') { + $option_price += $product_option_value['price']; + } elseif ($product_option_value['price_prefix'] == '-') { + $option_price -= $product_option_value['price']; + } + } + } + } + } + } elseif (($product_option['type'] == 'checkbox') && is_array($option[$product_option['product_option_id']])) { + foreach ($product_option['product_option_value'] as $product_option_value) { + if (!$product_option_value['subtract'] || ($product_option_value['quantity'] > 0)) { + if ((float)$product_option_value['price']) { + if (in_array($product_option_value['product_option_value_id'], $option[$product_option['product_option_id']])) { + if ($product_option_value['price_prefix'] == '+') { + $option_price += $product_option_value['price']; + } elseif ($product_option_value['price_prefix'] == '-') { + $option_price -= $product_option_value['price']; + } + } + } + } + } + } + } + } + + if ((float)$product_info['special']) { + $product_price = $this->tax->calculate(($product_info['special'] + $option_price) * $quantity, $product_info['tax_class_id'], true); + } else { + $product_price = $this->tax->calculate(($product_info['price'] + $option_price) * $quantity, $product_info['tax_class_id'], true); + } + } + + if ($setting['button']['product']['status']) { + $data['components'][] = 'buttons'; + $data['button_status'] = $setting['button']['product']['status']; + $data['button_insert_tag'] = html_entity_decode($setting['button']['product']['insert_tag']); + $data['button_insert_type'] = $setting['button']['product']['insert_type']; + $data['button_align'] = $setting['button']['product']['align']; + $data['button_size'] = $setting['button']['product']['size']; + $data['button_width'] = $setting['button_width'][$data['button_size']]; + $data['button_color'] = $setting['button']['product']['color']; + $data['button_shape'] = $setting['button']['product']['shape']; + $data['button_label'] = $setting['button']['product']['label']; + + $data['button_enable_funding'] = array(); + $data['button_disable_funding'] = array(); + + foreach ($setting['button_funding'] as $button_funding) { + if ($setting['button']['product']['funding'][$button_funding['code']] == 1) { + $data['button_enable_funding'][] = $button_funding['code']; + } + + if ($setting['button']['product']['funding'][$button_funding['code']] == 2) { + $data['button_disable_funding'][] = $button_funding['code']; } } } + + if ($setting['googlepay_button']['product']['status']) { + $data['components'][] = 'googlepay'; + $data['googlepay_button_status'] = $setting['googlepay_button']['product']['status']; + $data['googlepay_button_insert_tag'] = html_entity_decode($setting['googlepay_button']['product']['insert_tag']); + $data['googlepay_button_insert_type'] = $setting['googlepay_button']['product']['insert_type']; + $data['googlepay_button_align'] = $setting['googlepay_button']['product']['align']; + $data['googlepay_button_size'] = $setting['googlepay_button']['product']['size']; + $data['googlepay_button_width'] = $setting['googlepay_button_width'][$data['googlepay_button_size']]; + $data['googlepay_button_color'] = $setting['googlepay_button']['product']['color']; + $data['googlepay_button_shape'] = $setting['googlepay_button']['product']['shape']; + $data['googlepay_button_type'] = $setting['googlepay_button']['product']['type']; + + if ($product_price) { + $data['googlepay_amount'] = number_format($product_price * $data['currency_value'], $data['decimal_place'], '.', ''); + } + } + + if ($setting['applepay_button']['product']['status'] && $this->isApple()) { + $data['components'][] = 'applepay'; + $data['applepay_button_status'] = $setting['applepay_button']['product']['status']; + $data['applepay_button_insert_tag'] = html_entity_decode($setting['applepay_button']['product']['insert_tag']); + $data['applepay_button_insert_type'] = $setting['applepay_button']['product']['insert_type']; + $data['applepay_button_align'] = $setting['applepay_button']['product']['align']; + $data['applepay_button_size'] = $setting['applepay_button']['product']['size']; + $data['applepay_button_width'] = $setting['applepay_button_width'][$data['applepay_button_size']]; + $data['applepay_button_color'] = $setting['applepay_button']['product']['color']; + $data['applepay_button_shape'] = $setting['applepay_button']['product']['shape']; + $data['applepay_button_type'] = $setting['applepay_button']['product']['type']; + + if ($product_price) { + $data['applepay_amount'] = number_format($product_price * $data['currency_value'], $data['decimal_place'], '.', ''); + } + } + + if ($setting['message']['product']['status'] && !empty($setting['paylater_country'][$setting['general']['country_code']]) && ($data['currency_code'] == $setting['general']['currency_code'])) { + $data['components'][] = 'messages'; + $data['message_status'] = $setting['message']['product']['status']; + $data['message_insert_tag'] = html_entity_decode($setting['message']['product']['insert_tag']); + $data['message_insert_type'] = $setting['message']['product']['insert_type']; + $data['message_layout'] = $setting['message']['product']['layout']; + $data['message_logo_type'] = $setting['message']['product']['logo_type']; + $data['message_logo_position'] = $setting['message']['product']['logo_position']; + $data['message_text_color'] = $setting['message']['product']['text_color']; + $data['message_text_size'] = $setting['message']['product']['text_size']; + $data['message_flex_color'] = $setting['message']['product']['flex_color']; + $data['message_flex_ratio'] = $setting['message']['product']['flex_ratio']; + + if ($product_price) { + $data['message_amount'] = number_format($product_price * $data['currency_value'], $data['decimal_place'], '.', ''); + } + } } - + if (($this->request->post['page_code'] == 'cart') && ($this->cart->hasProducts() || !empty($this->session->data['vouchers']))) { if ($setting['button']['cart']['status']) { - $json['components'][] = 'buttons'; - $json['button_status'] = $setting['button']['cart']['status']; - $json['button_insert_tag'] = html_entity_decode($setting['button']['cart']['insert_tag']); - $json['button_insert_type'] = $setting['button']['cart']['insert_type']; - $json['button_align'] = $setting['button']['cart']['align']; - $json['button_size'] = $setting['button']['cart']['size']; - $json['button_width'] = $setting['button_width'][$json['button_size']]; - $json['button_color'] = $setting['button']['cart']['color']; - $json['button_shape'] = $setting['button']['cart']['shape']; - $json['button_label'] = $setting['button']['cart']['label']; - $json['button_tagline'] = $setting['button']['cart']['tagline']; - } - - if ($setting['message']['cart']['status'] && ($json['currency_code'] == $setting['general']['currency_code'])) { - $json['components'][] = 'messages'; - $json['message_status'] = $setting['message']['cart']['status']; - $json['message_insert_tag'] = html_entity_decode($setting['message']['cart']['insert_tag']); - $json['message_insert_type'] = $setting['message']['cart']['insert_type']; - $json['message_align'] = $setting['message']['cart']['align']; - $json['message_size'] = $setting['message']['cart']['size']; - $json['message_width'] = $setting['message_width'][$json['message_size']]; - $json['message_layout'] = $setting['message']['cart']['layout']; - $json['message_text_color'] = $setting['message']['cart']['text_color']; - $json['message_text_size'] = $setting['message']['cart']['text_size']; - $json['message_flex_color'] = $setting['message']['cart']['flex_color']; - $json['message_flex_ratio'] = $setting['message']['cart']['flex_ratio']; - + $data['components'][] = 'buttons'; + $data['button_status'] = $setting['button']['cart']['status']; + $data['button_insert_tag'] = html_entity_decode($setting['button']['cart']['insert_tag']); + $data['button_insert_type'] = $setting['button']['cart']['insert_type']; + $data['button_align'] = $setting['button']['cart']['align']; + $data['button_size'] = $setting['button']['cart']['size']; + $data['button_width'] = $setting['button_width'][$data['button_size']]; + $data['button_color'] = $setting['button']['cart']['color']; + $data['button_shape'] = $setting['button']['cart']['shape']; + $data['button_label'] = $setting['button']['cart']['label']; + + $data['button_enable_funding'] = array(); + $data['button_disable_funding'] = array(); + + foreach ($setting['button_funding'] as $button_funding) { + if ($setting['button']['cart']['funding'][$button_funding['code']] == 1) { + $data['button_enable_funding'][] = $button_funding['code']; + } + + if ($setting['button']['cart']['funding'][$button_funding['code']] == 2) { + $data['button_disable_funding'][] = $button_funding['code']; + } + } + } + + if ($setting['googlepay_button']['cart']['status']) { + $data['components'][] = 'googlepay'; + $data['googlepay_button_status'] = $setting['googlepay_button']['cart']['status']; + $data['googlepay_button_insert_tag'] = html_entity_decode($setting['googlepay_button']['cart']['insert_tag']); + $data['googlepay_button_insert_type'] = $setting['googlepay_button']['cart']['insert_type']; + $data['googlepay_button_align'] = $setting['googlepay_button']['cart']['align']; + $data['googlepay_button_size'] = $setting['googlepay_button']['cart']['size']; + $data['googlepay_button_width'] = $setting['googlepay_button_width'][$data['googlepay_button_size']]; + $data['googlepay_button_color'] = $setting['googlepay_button']['cart']['color']; + $data['googlepay_button_shape'] = $setting['googlepay_button']['cart']['shape']; + $data['googlepay_button_type'] = $setting['googlepay_button']['cart']['type']; + $item_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); - + $item_total += $product_price * $product['quantity']; } - + + if (!empty($this->session->data['vouchers'])) { + foreach ($this->session->data['vouchers'] as $voucher) { + $item_total += $voucher['amount']; + } + } + + $data['googlepay_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); + } + + if ($setting['applepay_button']['cart']['status'] && $this->isApple()) { + $data['components'][] = 'applepay'; + $data['applepay_button_status'] = $setting['applepay_button']['cart']['status']; + $data['applepay_button_insert_tag'] = html_entity_decode($setting['applepay_button']['cart']['insert_tag']); + $data['applepay_button_insert_type'] = $setting['applepay_button']['cart']['insert_type']; + $data['applepay_button_align'] = $setting['applepay_button']['cart']['align']; + $data['applepay_button_size'] = $setting['applepay_button']['cart']['size']; + $data['applepay_button_width'] = $setting['applepay_button_width'][$data['applepay_button_size']]; + $data['applepay_button_color'] = $setting['applepay_button']['cart']['color']; + $data['applepay_button_shape'] = $setting['applepay_button']['cart']['shape']; + $data['applepay_button_type'] = $setting['applepay_button']['cart']['type']; + + $item_total = 0; + + foreach ($this->cart->getProducts() as $product) { + $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); + + $item_total += $product_price * $product['quantity']; + } + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } + + $data['applepay_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); + } - $json['message_amount'] = number_format($item_total * $json['currency_value'], $json['decimal_place'], '.', ''); + if ($setting['message']['cart']['status'] && !empty($setting['paylater_country'][$setting['general']['country_code']]) && ($data['currency_code'] == $setting['general']['currency_code'])) { + $data['components'][] = 'messages'; + $data['message_status'] = $setting['message']['cart']['status']; + $data['message_insert_tag'] = html_entity_decode($setting['message']['cart']['insert_tag']); + $data['message_insert_type'] = $setting['message']['cart']['insert_type']; + $data['message_layout'] = $setting['message']['cart']['layout']; + $data['message_logo_type'] = $setting['message']['cart']['logo_type']; + $data['message_logo_position'] = $setting['message']['cart']['logo_position']; + $data['message_text_color'] = $setting['message']['cart']['text_color']; + $data['message_text_size'] = $setting['message']['cart']['text_size']; + $data['message_flex_color'] = $setting['message']['cart']['flex_color']; + $data['message_flex_ratio'] = $setting['message']['cart']['flex_ratio']; + + $item_total = 0; + + foreach ($this->cart->getProducts() as $product) { + $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); + + $item_total += $product_price * $product['quantity']; + } + + if (!empty($this->session->data['vouchers'])) { + foreach ($this->session->data['vouchers'] as $voucher) { + $item_total += $voucher['amount']; + } + } + + $data['message_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); } } - + if (($this->request->post['page_code'] == 'checkout') && ($this->cart->hasProducts() || !empty($this->session->data['vouchers']))) { if (!empty($this->session->data['order_id'])) { $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); } - + if ($setting['button']['checkout']['status']) { - $json['components'][] = 'buttons'; - $json['components'][] = 'funding-eligibility'; - $json['button_status'] = $setting['button']['checkout']['status']; - $json['button_align'] = $setting['button']['checkout']['align']; - $json['button_size'] = $setting['button']['checkout']['size']; - $json['button_width'] = $setting['button_width'][$json['button_size']]; - $json['button_color'] = $setting['button']['checkout']['color']; - $json['button_shape'] = $setting['button']['checkout']['shape']; - $json['button_label'] = $setting['button']['checkout']['label']; - - $json['button_enable_funding'] = []; - $json['button_disable_funding'] = []; - + $data['components'][] = 'buttons'; + $data['components'][] = 'funding-eligibility'; + $data['button_status'] = $setting['button']['checkout']['status']; + $data['button_align'] = $setting['button']['checkout']['align']; + $data['button_size'] = $setting['button']['checkout']['size']; + $data['button_width'] = $setting['button_width'][$data['button_size']]; + $data['button_color'] = $setting['button']['checkout']['color']; + $data['button_shape'] = $setting['button']['checkout']['shape']; + $data['button_label'] = $setting['button']['checkout']['label']; + + $data['button_enable_funding'] = array(); + $data['button_disable_funding'] = array(); + foreach ($setting['button_funding'] as $button_funding) { if ($setting['button']['checkout']['funding'][$button_funding['code']] == 1) { - $json['button_enable_funding'][] = $button_funding['code']; - } - + $data['button_enable_funding'][] = $button_funding['code']; + } + if ($setting['button']['checkout']['funding'][$button_funding['code']] == 2) { - $json['button_disable_funding'][] = $button_funding['code']; + $data['button_disable_funding'][] = $button_funding['code']; } } - + if (isset($this->session->data['payment_method']['code']) && ($this->session->data['payment_method']['code'] == 'paypal_paylater')) { - $json['button_funding_source'] = 'paylater'; + $data['button_funding_source'] = 'paylater'; } } - - if ($setting['googlepay_button']['status']) { - $json['components'][] = 'googlepay'; - $json['googlepay_button_status'] = $setting['googlepay_button']['status']; - $json['googlepay_button_align'] = $setting['googlepay_button']['align']; - $json['googlepay_button_size'] = $setting['googlepay_button']['size']; - $json['googlepay_button_width'] = $setting['googlepay_button_width'][$json['googlepay_button_size']]; - $json['googlepay_button_color'] = $setting['googlepay_button']['color']; - $json['googlepay_button_shape'] = $setting['googlepay_button']['shape']; - $json['googlepay_button_type'] = $setting['googlepay_button']['type']; - + + if ($setting['googlepay_button']['checkout']['status']) { + $data['components'][] = 'googlepay'; + $data['googlepay_button_status'] = $setting['googlepay_button']['checkout']['status']; + $data['googlepay_button_align'] = $setting['googlepay_button']['checkout']['align']; + $data['googlepay_button_size'] = $setting['googlepay_button']['checkout']['size']; + $data['googlepay_button_width'] = $setting['googlepay_button_width'][$data['googlepay_button_size']]; + $data['googlepay_button_color'] = $setting['googlepay_button']['checkout']['color']; + $data['googlepay_button_shape'] = $setting['googlepay_button']['checkout']['shape']; + $data['googlepay_button_type'] = $setting['googlepay_button']['checkout']['type']; + if (!empty($order_info)) { - $json['googlepay_amount'] = number_format($order_info['total'] * $json['currency_value'], $json['decimal_place'], '.', ''); + $data['googlepay_amount'] = number_format($order_info['total'] * $data['currency_value'], $data['decimal_place'], '.', ''); } else { $item_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); - + $item_total += $product_price * $product['quantity']; } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } - - $json['googlepay_amount'] = number_format($item_total * $json['currency_value'], $json['decimal_place'], '.', ''); + + $data['googlepay_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); } } - - if ($setting['applepay_button']['status']) { - $json['components'][] = 'applepay'; - $json['applepay_button_status'] = $setting['applepay_button']['status']; - $json['applepay_button_align'] = $setting['applepay_button']['align']; - $json['applepay_button_size'] = $setting['applepay_button']['size']; - $json['applepay_button_width'] = $setting['applepay_button_width'][$json['applepay_button_size']]; - $json['applepay_button_color'] = $setting['applepay_button']['color']; - $json['applepay_button_shape'] = $setting['applepay_button']['shape']; - $json['applepay_button_type'] = $setting['applepay_button']['type']; - + + if ($setting['applepay_button']['checkout']['status'] && $this->isApple()) { + $data['components'][] = 'applepay'; + $data['applepay_button_status'] = $setting['applepay_button']['checkout']['status']; + $data['applepay_button_align'] = $setting['applepay_button']['checkout']['align']; + $data['applepay_button_size'] = $setting['applepay_button']['checkout']['size']; + $data['applepay_button_width'] = $setting['applepay_button_width'][$data['applepay_button_size']]; + $data['applepay_button_color'] = $setting['applepay_button']['checkout']['color']; + $data['applepay_button_shape'] = $setting['applepay_button']['checkout']['shape']; + $data['applepay_button_type'] = $setting['applepay_button']['checkout']['type']; + if (!empty($order_info)) { - $json['applepay_amount'] = number_format($order_info['total'] * $json['currency_value'], $json['decimal_place'], '.', ''); + $data['applepay_amount'] = number_format($order_info['total'] * $data['currency_value'], $data['decimal_place'], '.', ''); } else { $item_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); - + $item_total += $product_price * $product['quantity']; } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } - - $json['applepay_amount'] = number_format($item_total * $json['currency_value'], $json['decimal_place'], '.', ''); + + $data['applepay_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); } } - - if ($setting['card']['status']) { - $json['components'][] = 'hosted-fields'; - $json['card_status'] = $setting['card']['status']; - $json['card_align'] = $setting['card']['align']; - $json['card_size'] = $setting['card']['size']; - $json['card_width'] = $setting['card_width'][$json['card_size']]; - $json['card_secure_status'] = $setting['card']['secure_status']; + + if ($setting['card']['status']) { + $data['components'][] = 'card-fields'; + $data['card_status'] = $setting['card']['status']; + $data['card_align'] = $setting['card']['align']; + $data['card_size'] = $setting['card']['size']; + $data['card_width'] = $setting['card_width'][$data['card_size']]; + + $data['card_customer_tokens'] = array(); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $card_customer_tokens = $this->model_extension_payment_paypal->getPayPalCustomerTokens($this->customer->getId(), 'card'); + + foreach ($card_customer_tokens as $card_customer_token) { + $data['card_customer_tokens'][] = array( + 'vault_id' => $card_customer_token['vault_id'], + 'card_type' => $card_customer_token['card_type'], + 'card_number' => sprintf($this->language->get('text_card_number'), $card_customer_token['card_nice_type'], $card_customer_token['card_last_digits']) + ); + } + } } - - if ($setting['message']['checkout']['status'] && ($json['currency_code'] == $setting['general']['currency_code'])) { - $json['components'][] = 'messages'; - $json['message_status'] = $setting['message']['checkout']['status']; - $json['message_align'] = $setting['message']['checkout']['align']; - $json['message_size'] = $setting['message']['checkout']['size']; - $json['message_width'] = $setting['message_width'][$json['message_size']]; - $json['message_layout'] = $setting['message']['checkout']['layout']; - $json['message_text_color'] = $setting['message']['checkout']['text_color']; - $json['message_text_size'] = $setting['message']['checkout']['text_size']; - $json['message_flex_color'] = $setting['message']['checkout']['flex_color']; - $json['message_flex_ratio'] = $setting['message']['checkout']['flex_ratio']; - + + if ($setting['message']['checkout']['status'] && !empty($setting['paylater_country'][$setting['general']['country_code']]) && ($data['currency_code'] == $setting['general']['currency_code'])) { + $data['components'][] = 'messages'; + $data['message_status'] = $setting['message']['checkout']['status']; + $data['message_layout'] = $setting['message']['checkout']['layout']; + $data['message_logo_type'] = $setting['message']['checkout']['logo_type']; + $data['message_logo_position'] = $setting['message']['checkout']['logo_position']; + $data['message_text_color'] = $setting['message']['checkout']['text_color']; + $data['message_text_size'] = $setting['message']['checkout']['text_size']; + $data['message_flex_color'] = $setting['message']['checkout']['flex_color']; + $data['message_flex_ratio'] = $setting['message']['checkout']['flex_ratio']; + if (!empty($order_info)) { - $json['message_amount'] = number_format($order_info['total'] * $json['currency_value'], $json['decimal_place'], '.', ''); + $data['message_amount'] = number_format($order_info['total'] * $data['currency_value'], $data['decimal_place'], '.', ''); } else { $item_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = $this->tax->calculate($product['price'], $product['tax_class_id'], true); - + $item_total += $product_price * $product['quantity']; } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } - - $json['message_amount'] = number_format($item_total * $json['currency_value'], $json['decimal_place'], '.', ''); + + $data['message_amount'] = number_format($item_total * $data['currency_value'], $data['decimal_place'], '.', ''); } } } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $json['partner_id'], - 'client_id' => $json['client_id'], - 'secret' => $json['secret'], - 'environment' => $json['environment'], - 'partner_attribution_id' => $json['partner_attribution_id'] - ]; - + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], + 'partner_attribution_id' => $data['partner_attribution_id'] + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ - 'grant_type' => 'client_credentials' - ]; - - $paypal->setAccessToken($token_info); - - $json['client_token'] = $paypal->getClientToken(); - + + $token_info = array( + 'grant_type' => 'client_credentials', + ); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), 'paypal'); + + if (!empty($paypal_customer_token['vault_customer_id'])) { + $token_info['response_type'] = 'id_token'; + $token_info['target_customer_id'] = $paypal_customer_token['vault_customer_id']; + } + } + + $result = $paypal->setAccessToken($token_info); + + if ($setting['general']['vault_status'] && !empty($result['id_token'])) { + $data['id_token'] = $result['id_token']; + } + + $data['client_token'] = $paypal->getClientToken(); + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } @@ -539,42 +737,45 @@ public function getData(): void { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Create Order - * - * @return void - */ - public function createOrder(): void { + + public function createOrder() { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + if (!empty($this->request->post['page_code']) && !empty($this->request->post['payment_type'])) { $page_code = $this->request->post['page_code']; $payment_type = $this->request->post['payment_type']; - - $errors = []; - - $json['order_id'] = ''; - + + $payment_method = ''; + + if ($payment_type == 'button') { + $payment_method = 'paypal'; + } + + if ($payment_type == 'card') { + $payment_method = 'card'; + } + + $errors = array(); + + $data['paypal_order_id'] = ''; + $data['url'] = ''; + if (!empty($this->request->post['product'])) { $this->request->post['product'] = $this->unserialize($this->request->post['product']); } - + if (($page_code == 'product') && (!empty($this->request->post['product']['product_id']))) { $product = $this->request->post['product']; - $product_id = (int)$product['product_id']; - + $this->load->model('catalog/product'); $product_info = $this->model_catalog_product->getProduct($product_id); @@ -589,104 +790,99 @@ public function createOrder(): void { if (isset($product['option'])) { $option = array_filter($product['option']); } else { - $option = []; + $option = array(); } - $product_options = $this->model_catalog_product->getOptions($product_id); + $product_options = $this->model_catalog_product->getProductOptions($product_id); foreach ($product_options as $product_option) { if ($product_option['required'] && empty($option[$product_option['product_option_id']])) { $errors[] = sprintf($this->language->get('error_required'), $product_option['name']); } } - - if (isset($product['subscription_plan_id'])) { - $subscription_plan_id = $product['subscription_plan_id']; + + if (isset($product['recurring_id'])) { + $recurring_id = $product['recurring_id']; } else { - $subscription_plan_id = 0; + $recurring_id = 0; } - $this->load->model('catalog/subscription_plan'); - - $filter_data = [ - 'filter_name' => $product_info['name'] - ]; - - $subscription_plans = $this->model_catalog_subscription_plan->getSubscriptionPlans($filter_data); + $recurrings = $this->model_catalog_product->getProfiles($product_info['product_id']); - if ($subscription_plans) { - $subscription_plan_ids = []; + if ($recurrings) { + $recurring_ids = array(); - foreach ($subscription_plans as $subscription_plan) { - $subscription_plan_ids[] = $subscription_plan['subscription_plan_id']; + foreach ($recurrings as $recurring) { + $recurring_ids[] = $recurring['recurring_id']; } - if (!in_array($subscription_plan_id, $subscription_plan_ids)) { - $errors[] = $this->language->get('error_subscription_required'); + if (!in_array($recurring_id, $recurring_ids)) { + $errors[] = $this->language->get('error_recurring_required'); } } - - if (!$errors) { - if (!$this->model_extension_payment_paypal->hasProductInCart($product_id, $option, $subscription_plan_id)) { - $this->cart->add($product_id, $quantity, $option, $subscription_plan_id); + + if (!$errors) { + if (!$this->model_extension_payment_paypal->hasProductInCart($product_id, $option, $recurring_id)) { + $this->cart->add($product_id, $quantity, $option, $recurring_id); } - + // Unset all shipping and payment methods unset($this->session->data['shipping_method']); unset($this->session->data['shipping_methods']); unset($this->session->data['payment_method']); unset($this->session->data['payment_methods']); - } + } } } - + if ($page_code == 'checkout') { $this->load->model('checkout/order'); - + $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - - $shipping_info = []; + + $shipping_info = array(); if ($this->cart->hasShipping()) { $shipping_info['name']['full_name'] = $order_info['shipping_firstname']; - $shipping_info['name']['full_name'] .= ($order_info['shipping_lastname'] ? (' ' . $order_info['shipping_lastname']) : ''); + $shipping_info['name']['full_name'] .= ($order_info['shipping_lastname'] ? (' ' . $order_info['shipping_lastname']) : ''); $shipping_info['address']['address_line_1'] = $order_info['shipping_address_1']; - $shipping_info['address']['address_line_2'] = $order_info['shipping_address_2']; + $shipping_info['address']['address_line_2'] = $order_info['shipping_address_2']; $shipping_info['address']['admin_area_1'] = $order_info['shipping_zone']; $shipping_info['address']['admin_area_2'] = $order_info['shipping_city']; $shipping_info['address']['postal_code'] = $order_info['shipping_postcode']; - + if ($order_info['shipping_country_id']) { $this->load->model('localisation/country'); - + $country_info = $this->model_localisation_country->getCountry($order_info['shipping_country_id']); - + if ($country_info) { $shipping_info['address']['country_code'] = $country_info['iso_code_2']; } } } } - - if (!$errors) { - $_config = new \Config(); + + if (!$errors) { + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $merchant_id = $this->config->get('payment_paypal_merchant_id'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; - $transaction_method = $setting['general']['transaction_method']; - + $vault_status = $setting['general']['vault_status']; + $transaction_method = $setting['general']['transaction_method']; + $currency_code = $this->session->data['currency']; $currency_value = $this->currency->getValue($this->session->data['currency']); - + if ((($payment_type == 'button') || ($payment_type == 'googlepay_button') || ($payment_type == 'applepay_button')) && empty($setting['currency'][$currency_code]['status'])) { $currency_code = $setting['general']['currency_code']; $currency_value = $setting['general']['currency_value']; @@ -696,48 +892,57 @@ public function createOrder(): void { $currency_code = $setting['general']['card_currency_code']; $currency_value = $setting['general']['card_currency_value']; } - + $decimal_place = $setting['currency'][$currency_code]['decimal_place']; - + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - - $paypal = new \PayPal($paypal_info); - - $token_info = [ + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - - $item_info = []; - + + $item_info = array(); + $item_total = 0; $tax_total = 0; - + + $this->load->model('tool/image'); + foreach ($this->cart->getProducts() as $product) { $product_price = number_format($product['price'] * $currency_value, $decimal_place, '.', ''); + + $product_info = array(); + + $product_info['name'] = $product['name']; + $product_info['quantity'] = $product['quantity']; + $product_info['sku'] = $product['model']; + $product_info['url'] = $this->url->link('product/product', 'product_id=' . $product['product_id'], true); + + if ($product['image']) { + $product_info['image_url'] = $this->model_tool_image->resize($product['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_thumb_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_thumb_height')); + } + + $product_info['unit_amount'] = array( + 'currency_code' => $currency_code, + 'value' => $product_price + ); - $item_info[] = [ - 'name' => $product['name'], - 'sku' => $product['model'], - 'url' => $this->url->link('product/product', 'product_id = ' . $product['product_id'], true), - 'quantity' => $product['quantity'], - 'unit_amount' => [ - 'currency_code' => $currency_code, - 'value' => $product_price - ] - ]; - + $item_info[] = $product_info; + $item_total += $product_price * $product['quantity']; - + if ($product['tax_class_id']) { $tax_rates = $this->tax->getRates($product['price'], $product['tax_class_id']); @@ -746,300 +951,336 @@ public function createOrder(): void { } } } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { - $item_info[] = [ - 'name' => $voucher['description'], - 'quantity' => 1, - 'unit_amount' => [ - 'currency_code' => $currency_code, - 'value' => $voucher['amount'] - ] - ]; - + $voucher_info = array(); + + $voucher_info['name'] = $voucher['description']; + $voucher_info['quantity'] = 1; + + $voucher_info['unit_amount'] = array( + 'currency_code' => $currency_code, + 'value' => $voucher['amount'] + ); + + $item_info[] = $voucher_info; + $item_total += $voucher['amount']; } } - + $item_total = number_format($item_total, $decimal_place, '.', ''); $tax_total = number_format($tax_total * $currency_value, $decimal_place, '.', ''); $order_total = number_format($item_total + $tax_total, $decimal_place, '.', ''); - - if ($page_code == 'checkout' && isset($order_info)) { + + if ($page_code == 'checkout') { $discount_total = 0; $handling_total = 0; $shipping_total = 0; - + if (isset($this->session->data['shipping_method'])) { $shipping_total = $this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], true); $shipping_total = number_format($shipping_total * $currency_value, $decimal_place, '.', ''); } - + $order_total = number_format($order_info['total'] * $currency_value, $decimal_place, '.', ''); - + $rebate = number_format($item_total + $tax_total + $shipping_total - $order_total, $decimal_place, '.', ''); - + if ($rebate > 0) { $discount_total = $rebate; } elseif ($rebate < 0) { $handling_total = -$rebate; } - } - - $amount_info = []; - + } + + $amount_info = array(); + $amount_info['currency_code'] = $currency_code; $amount_info['value'] = $order_total; - - $amount_info['breakdown']['item_total'] = [ + + $amount_info['breakdown']['item_total'] = array( 'currency_code' => $currency_code, - 'value' => $item_total - ]; - - $amount_info['breakdown']['tax_total'] = [ + 'value' => $item_total + ); + + $amount_info['breakdown']['tax_total'] = array( 'currency_code' => $currency_code, - 'value' => $tax_total - ]; - - if ($page_code == 'checkout' && isset($shipping_total) && isset($handling_total) && isset($discount_total) && isset($order_info) && isset($shipping_info)) { - $amount_info['breakdown']['shipping'] = [ + 'value' => $tax_total + ); + + if ($page_code == 'checkout') { + $amount_info['breakdown']['shipping'] = array( 'currency_code' => $currency_code, - 'value' => $shipping_total - ]; - - $amount_info['breakdown']['handling'] = [ + 'value' => $shipping_total + ); + + $amount_info['breakdown']['handling'] = array( 'currency_code' => $currency_code, - 'value' => $handling_total - ]; - - $amount_info['breakdown']['discount'] = [ + 'value' => $handling_total + ); + + $amount_info['breakdown']['discount'] = array( 'currency_code' => $currency_code, - 'value' => $discount_total - ]; + 'value' => $discount_total + ); } - - $paypal_order_info = []; - + + $paypal_order_info = array(); + $paypal_order_info['intent'] = strtoupper($transaction_method); - $paypal_order_info['purchase_units'][0]['reference_id'] = 'default'; $paypal_order_info['purchase_units'][0]['items'] = $item_info; $paypal_order_info['purchase_units'][0]['amount'] = $amount_info; - - if ($page_code == 'checkout' && isset($order_info)) { + + if ($page_code == 'checkout') { $paypal_order_info['purchase_units'][0]['description'] = 'Your order ' . $order_info['order_id']; $paypal_order_info['purchase_units'][0]['invoice_id'] = $order_info['order_id'] . '_' . date('Ymd_His'); - - if ($this->cart->hasShipping() && isset($shipping_info)) { + + if ($this->cart->hasShipping()) { $paypal_order_info['purchase_units'][0]['shipping'] = $shipping_info; } } - - if ($this->cart->hasShipping()) { + + if ($this->cart->hasShipping()) { $shipping_preference = 'GET_FROM_FILE'; } else { $shipping_preference = 'NO_SHIPPING'; } - + $paypal_order_info['application_context']['shipping_preference'] = $shipping_preference; - - if ($this->cart->hasSubscription()) { - $payment_method = ''; - - if ($payment_type == 'button') { - $payment_method = 'paypal'; - } - - if ($payment_type == 'card') { - $payment_method = 'card'; + + if ($setting['general']['vault_status'] && ($this->customer->isLogged() || $this->cart->hasRecurringProducts())) { + if ($payment_method == 'paypal') { + $paypal_customer_token = array(); + + if ($this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), $payment_method); + } + + if (empty($paypal_customer_token['vault_id'])) { + $paypal_order_info['payment_source'][$payment_method]['attributes']['vault'] = array( + 'permit_multiple_payment_tokens' => 'false', + 'store_in_vault' => 'ON_SUCCESS', + 'usage_type' => 'MERCHANT', + 'customer_type' => 'CONSUMER' + ); + } } - - if ($payment_method) { - $paypal_order_info['payment_source'][$payment_method]['attributes']['vault'] = [ - 'store_in_vault' => 'ON_SUCCESS', - 'usage_type' => 'MERCHANT', - 'customer_type' => 'CONSUMER' - ]; - - $paypal_order_info['payment_source']['paypal']['experience_context'] = [ - 'return_url' => $this->url->link('checkout/success', '', true), - 'cancel_url' => $this->url->link('checkout/success', '', true) - ]; + + if ($payment_method == 'card') { + if (isset($this->request->post['index'])) { + $card_token_index = $this->request->post['index']; + + $card_customer_tokens = $this->model_extension_payment_paypal->getPayPalCustomerTokens($this->customer->getId(), $payment_method); + + if (!empty($card_customer_tokens[$card_token_index]['vault_id'])) { + $paypal_order_info['payment_source'][$payment_method]['vault_id'] = $card_customer_tokens[$card_token_index]['vault_id']; + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['payment_initiator'] = 'CUSTOMER'; + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['payment_type'] = 'ONE_TIME'; + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['usage'] = 'SUBSEQUENT'; + } + } else { + if (!empty($this->request->post['card_save']) || $this->cart->hasRecurringProducts()) { + $paypal_order_info['payment_source'][$payment_method]['attributes']['vault']['store_in_vault'] = 'ON_SUCCESS'; + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['payment_initiator'] = 'CUSTOMER'; + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['usage'] = 'FIRST'; + + if ($this->cart->hasRecurringProducts()) { + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['payment_type'] = 'UNSCHEDULED'; + } else { + $paypal_order_info['payment_source'][$payment_method]['stored_credential']['payment_type'] = 'ONE_TIME'; + } + } + } } } - + + if ($payment_method) { + $paypal_order_info['payment_source'][$payment_method]['attributes']['verification']['method'] = strtoupper($setting['card']['secure_method']); + $paypal_order_info['payment_source'][$payment_method]['experience_context']['return_url'] = $this->url->link('extension/payment/paypal', 'callback_token=' . $setting['general']['callback_token'], true); + $paypal_order_info['payment_source'][$payment_method]['experience_context']['cancel_url'] = $this->url->link('checkout/checkout', '', true); + } + $result = $paypal->createOrder($paypal_order_info); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } - - $json['paypal_order_id'] = ''; - + if (isset($result['id']) && isset($result['status']) && !$this->error) { $this->model_extension_payment_paypal->log($result, 'Create Order'); - + if ($result['status'] == 'VOIDED') { $this->error['warning'] = sprintf($this->language->get('error_order_voided'), $this->url->link('information/contact', '', true)); } - - if ($result['status'] == 'COMPLETED') { + + if (($result['status'] == 'COMPLETED') && empty($paypal_order_info['payment_source']['card']['vault_id'])) { $this->error['warning'] = sprintf($this->language->get('error_order_completed'), $this->url->link('information/contact', '', true)); } - + + if (($result['status'] == 'COMPLETED') && !empty($paypal_order_info['payment_source']['card']['vault_id'])) { + $data['url'] = $this->url->link('checkout/success', '', true); + } + + if (($result['status'] == 'PAYER_ACTION_REQUIRED') && !empty($paypal_order_info['payment_source']['card']['vault_id'])) { + foreach ($result['links'] as $link) { + if ($link['rel'] == 'payer-action') { + $data['url'] = $link['href']; + + $this->session->data['paypal_order_id'] = $result['id']; + $this->session->data['paypal_card_token_index'] = $this->request->post['index']; + } + } + } + if (!$this->error) { - $json['paypal_order_id'] = $result['id']; + $data['paypal_order_id'] = $result['id']; } } } else { $this->error['warning'] = implode(' ', $errors); } } - - $json['error'] = $this->error; - + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Approve Order - * - * @return void - */ - public function approveOrder(): void { + + public function approveOrder() { $this->load->language('extension/payment/paypal'); - - $json = []; - + $this->load->model('extension/payment/paypal'); - + if (!empty($this->request->post['page_code']) && !empty($this->request->post['payment_type'])) { $page_code = $this->request->post['page_code']; $payment_type = $this->request->post['payment_type']; - + if ($page_code != 'checkout') { if (isset($this->request->post['paypal_order_id'])) { - $this->session->data['paypal_order_id'] = (int)$this->request->post['paypal_order_id']; - } else { - $json['url'] = $this->url->link('checkout/cart', '', true); - + $this->session->data['paypal_order_id'] = $this->request->post['paypal_order_id']; + } else { + $data['url'] = $this->url->link('checkout/cart', '', true); + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - + // check checkout can continue due to stock checks or vouchers if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { - $json['url'] = $this->url->link('checkout/cart', '', true); - + $data['url'] = $this->url->link('checkout/cart', '', true); + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } // if user not logged in check that the guest checkout is allowed - if (!$this->customer->isLogged() && (!$this->config->get('config_checkout_guest') || $this->config->get('config_customer_price') || $this->cart->hasDownload() || $this->cart->hasSubscription())) { - $json['url'] = $this->url->link('checkout/cart', '', true); - + if (!$this->customer->isLogged() && (!$this->config->get('config_checkout_guest') || $this->config->get('config_customer_price') || $this->cart->hasDownload() || $this->cart->hasRecurringProducts())) { + $data['url'] = $this->url->link('checkout/cart', '', true); + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } } - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $vault_status = $setting['general']['vault_status']; $transaction_method = $setting['general']['transaction_method']; - + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - - $paypal = new \PayPal($paypal_info); - - $token_info = [ + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + if ($page_code != 'checkout') { $paypal_order_id = $this->session->data['paypal_order_id']; - + $paypal_order_info = $paypal->getOrder($paypal_order_id); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } - + if ($paypal_order_info && !$this->error) { $this->load->model('account/customer'); $this->load->model('account/address'); - + unset($this->session->data['shipping_method']); unset($this->session->data['shipping_methods']); unset($this->session->data['payment_method']); unset($this->session->data['payment_methods']); - + if ($this->customer->isLogged()) { $customer_info = $this->model_account_customer->getCustomer($this->customer->getId()); @@ -1052,19 +1293,19 @@ public function approveOrder(): void { $this->session->data['guest']['custom_field'] = json_decode($customer_info['custom_field'], true); } else { $this->session->data['guest']['customer_id'] = 0; - $this->session->data['guest']['customer_group_id'] = (int)$this->config->get('config_customer_group_id'); - $this->session->data['guest']['firstname'] = ($paypal_order_info['payer']['name']['given_name'] ?? ''); - $this->session->data['guest']['lastname'] = ($paypal_order_info['payer']['name']['surname'] ?? ''); - $this->session->data['guest']['email'] = ($paypal_order_info['payer']['email_address'] ?? ''); - $this->session->data['guest']['telephone'] = ''; - $this->session->data['guest']['custom_field'] = []; + $this->session->data['guest']['customer_group_id'] = $this->config->get('config_customer_group_id'); + $this->session->data['guest']['firstname'] = (isset($paypal_order_info['payer']['name']['given_name']) ? $paypal_order_info['payer']['name']['given_name'] : ''); + $this->session->data['guest']['lastname'] = (isset($paypal_order_info['payer']['name']['surname']) ? $paypal_order_info['payer']['name']['surname'] : ''); + $this->session->data['guest']['email'] = (isset($paypal_order_info['payer']['email_address']) ? $paypal_order_info['payer']['email_address'] : ''); + $this->session->data['guest']['telephone'] = (isset($paypal_order_info['payer']['phone']['phone_number']['national_number']) ? $paypal_order_info['payer']['phone']['phone_number']['national_number'] : ''); + $this->session->data['guest']['custom_field'] = array(); } - + if ($this->customer->isLogged() && $this->customer->getAddressId()) { $this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); } else { - $this->session->data['payment_address']['firstname'] = ($paypal_order_info['payer']['name']['given_name'] ?? ''); - $this->session->data['payment_address']['lastname'] = ($paypal_order_info['payer']['name']['surname'] ?? ''); + $this->session->data['payment_address']['firstname'] = (isset($paypal_order_info['payer']['name']['given_name']) ? $paypal_order_info['payer']['name']['given_name'] : ''); + $this->session->data['payment_address']['lastname'] = (isset($paypal_order_info['payer']['name']['surname']) ? $paypal_order_info['payer']['name']['surname'] : ''); $this->session->data['payment_address']['company'] = ''; $this->session->data['payment_address']['address_1'] = ''; $this->session->data['payment_address']['address_2'] = ''; @@ -1075,18 +1316,18 @@ public function approveOrder(): void { $this->session->data['payment_address']['address_format'] = ''; $this->session->data['payment_address']['zone'] = ''; $this->session->data['payment_address']['zone_id'] = 0; - $this->session->data['payment_address']['custom_field'] = []; - + $this->session->data['payment_address']['custom_field'] = array(); + if (isset($paypal_order_info['payer']['address']['country_code'])) { $country_info = $this->model_extension_payment_paypal->getCountryByCode($paypal_order_info['payer']['address']['country_code']); - + if ($country_info) { $this->session->data['payment_address']['country'] = $country_info['name']; $this->session->data['payment_address']['country_id'] = $country_info['country_id']; } } } - + if ($this->cart->hasShipping()) { if ($this->customer->isLogged() && $this->customer->getAddressId()) { $this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); @@ -1097,32 +1338,32 @@ public function approveOrder(): void { unset($shipping_name[0]); $shipping_lastname = implode(' ', $shipping_name); } - - $this->session->data['shipping_address']['firstname'] = ($shipping_firstname ?? ''); - $this->session->data['shipping_address']['lastname'] = ($shipping_lastname ?? ''); + + $this->session->data['shipping_address']['firstname'] = (isset($shipping_firstname) ? $shipping_firstname : ''); + $this->session->data['shipping_address']['lastname'] = (isset($shipping_lastname) ? $shipping_lastname : ''); $this->session->data['shipping_address']['company'] = ''; - $this->session->data['shipping_address']['address_1'] = ($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_1'] ?? ''); - $this->session->data['shipping_address']['address_2'] = ($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_2'] ?? ''); - $this->session->data['shipping_address']['city'] = ($paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_2'] ?? ''); - $this->session->data['shipping_address']['postcode'] = ($paypal_order_info['purchase_units'][0]['shipping']['address']['postal_code'] ?? ''); + $this->session->data['shipping_address']['address_1'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_1']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_1'] : ''); + $this->session->data['shipping_address']['address_2'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_2']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_2'] : ''); + $this->session->data['shipping_address']['city'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_2']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_2'] : ''); + $this->session->data['shipping_address']['postcode'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['postal_code']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['postal_code'] : ''); $this->session->data['shipping_address']['country'] = ''; $this->session->data['shipping_address']['country_id'] = 0; $this->session->data['shipping_address']['address_format'] = ''; $this->session->data['shipping_address']['zone'] = ''; $this->session->data['shipping_address']['zone_id'] = 0; - $this->session->data['shipping_address']['custom_field'] = []; - + $this->session->data['shipping_address']['custom_field'] = array(); + if (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['country_code'])) { $country_info = $this->model_extension_payment_paypal->getCountryByCode($paypal_order_info['purchase_units'][0]['shipping']['address']['country_code']); - + if ($country_info) { $this->session->data['shipping_address']['country_id'] = $country_info['country_id']; $this->session->data['shipping_address']['country'] = $country_info['name']; $this->session->data['shipping_address']['address_format'] = $country_info['address_format']; - + if (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_1'])) { $zone_info = $this->model_extension_payment_paypal->getZoneByCode($country_info['country_id'], $paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_1']); - + if ($zone_info) { $this->session->data['shipping_address']['zone_id'] = $zone_info['zone_id']; $this->session->data['shipping_address']['zone'] = $zone_info['name']; @@ -1132,159 +1373,279 @@ public function approveOrder(): void { } } } + + if (($payment_type == 'googlepay_button') && !empty($this->request->post['payment_data'])) { + $payment_data = json_decode(htmlspecialchars_decode($this->request->post['payment_data']), true); + + if (isset($payment_data['paymentMethodData']['info']['billingAddress']['name'])) { + $payment_name = explode(' ', $payment_data['paymentMethodData']['info']['billingAddress']['name']); + $payment_firstname = $payment_name[0]; + unset($payment_name[0]); + $payment_lastname = implode(' ', $payment_name); + } + + $this->session->data['guest']['firstname'] = (isset($payment_firstname) ? $payment_firstname : ''); + $this->session->data['guest']['lastname'] = (isset($payment_lastname) ? $payment_lastname : ''); + $this->session->data['guest']['email'] = (isset($payment_data['email']) ? $payment_data['email'] : ''); + $this->session->data['guest']['telephone'] = (isset($payment_data['paymentMethodData']['info']['billingAddress']['phoneNumber']) ? $payment_data['paymentMethodData']['info']['billingAddress']['phoneNumber'] : ''); + + $this->session->data['payment_address']['firstname'] = (isset($shipping_firstname) ? $shipping_firstname : ''); + $this->session->data['payment_address']['lastname'] = (isset($shipping_lastname) ? $shipping_lastname : ''); + $this->session->data['payment_address']['address_1'] = (isset($payment_data['paymentMethodData']['info']['billingAddress']['address1']) ? $payment_data['paymentMethodData']['info']['billingAddress']['address1'] : ''); + $this->session->data['payment_address']['city'] = (isset($payment_data['paymentMethodData']['info']['billingAddress']['locality']) ? $payment_data['paymentMethodData']['info']['billingAddress']['locality'] : ''); + $this->session->data['payment_address']['postcode'] = (isset($payment_data['paymentMethodData']['info']['billingAddress']['postalCode']) ? $payment_data['paymentMethodData']['info']['billingAddress']['postalCode'] : ''); + + if (isset($payment_data['paymentMethodData']['info']['billingAddress']['countryCode'])) { + $country_info = $this->model_extension_payment_paypal->getCountryByCode($payment_data['paymentMethodData']['info']['billingAddress']['countryCode']); + + if ($country_info) { + $this->session->data['payment_address']['country'] = $country_info['name']; + $this->session->data['payment_address']['country_id'] = $country_info['country_id']; + } + } + + if ($this->cart->hasShipping()) { + if (isset($payment_data['shippingAddress']['name'])) { + $shipping_name = explode(' ', $payment_data['shippingAddress']['name']); + $shipping_firstname = $shipping_name[0]; + unset($shipping_name[0]); + $shipping_lastname = implode(' ', $shipping_name); + } + + $this->session->data['shipping_address']['firstname'] = (isset($shipping_firstname) ? $shipping_firstname : ''); + $this->session->data['shipping_address']['lastname'] = (isset($shipping_lastname) ? $shipping_lastname : ''); + $this->session->data['shipping_address']['address_1'] = (isset($payment_data['shippingAddress']['address1']) ? $payment_data['shippingAddress']['address1'] : ''); + $this->session->data['shipping_address']['city'] = (isset($payment_data['shippingAddress']['locality']) ? $payment_data['shippingAddress']['locality'] : ''); + $this->session->data['shipping_address']['postcode'] = (isset($payment_data['shippingAddress']['postalCode']) ? $payment_data['shippingAddress']['postalCode'] : ''); + + if (isset($payment_data['shippingAddress']['countryCode'])) { + $country_info = $this->model_extension_payment_paypal->getCountryByCode($payment_data['shippingAddress']['countryCode']); + + if ($country_info) { + $this->session->data['shipping_address']['country'] = $country_info['name']; + $this->session->data['shipping_address']['country_id'] = $country_info['country_id']; + } + } + } + } + + if (($payment_type == 'applepay_button') && !empty($this->request->post['payment_data'])) { + $payment_data = json_decode(htmlspecialchars_decode($this->request->post['payment_data']), true); + + $this->session->data['guest']['firstname'] = (isset($payment_data['billingContact']['givenName']) ? $payment_data['billingContact']['givenName'] : ''); + $this->session->data['guest']['lastname'] = (isset($payment_data['billingContact']['familyName']) ? $payment_data['billingContact']['familyName'] : ''); + $this->session->data['guest']['email'] = (isset($payment_data['shippingContact']['emailAddress']) ? $payment_data['shippingContact']['emailAddress'] : ''); + $this->session->data['guest']['telephone'] = (isset($payment_data['shippingContact']['phoneNumber']) ? $payment_data['shippingContact']['phoneNumber'] : ''); + + $this->session->data['payment_address']['firstname'] = (isset($payment_data['billingContact']['givenName']) ? $payment_data['billingContact']['givenName'] : ''); + $this->session->data['payment_address']['lastname'] = (isset($payment_data['billingContact']['familyName']) ? $payment_data['billingContact']['familyName'] : ''); + $this->session->data['payment_address']['address_1'] = (isset($payment_data['billingContact']['addressLines']) ? $payment_data['billingContact']['addressLines'] : ''); + $this->session->data['payment_address']['city'] = (isset($payment_data['billingContact']['locality']) ? $payment_data['billingContact']['locality'] : ''); + $this->session->data['payment_address']['postcode'] = (isset($payment_data['billingContact']['postalCode']) ? $payment_data['billingContact']['postalCode'] : ''); + + if (isset($payment_data['billingContact']['countryCode'])) { + $country_info = $this->model_extension_payment_paypal->getCountryByCode($payment_data['billingContact']['countryCode']); + + if ($country_info) { + $this->session->data['payment_address']['country'] = $country_info['name']; + $this->session->data['payment_address']['country_id'] = $country_info['country_id']; + } + } + + if ($this->cart->hasShipping()) { + $this->session->data['shipping_address']['firstname'] = (isset($payment_data['shippingContact']['givenName']) ? $payment_data['shippingContact']['givenName'] : ''); + $this->session->data['shipping_address']['lastname'] = (isset($payment_data['shippingContact']['familyName']) ? $payment_data['shippingContact']['familyName'] : ''); + $this->session->data['shipping_address']['address_1'] = (isset($payment_data['shippingContact']['addressLines']) ? $payment_data['shippingContact']['addressLines'] : ''); + $this->session->data['shipping_address']['city'] = (isset($payment_data['shippingContact']['locality']) ? $payment_data['shippingContact']['locality'] : ''); + $this->session->data['shipping_address']['postcode'] = (isset($payment_data['shippingContact']['postalCode']) ? $payment_data['shippingContact']['postalCode'] : ''); + + if (isset($payment_data['shippingContact']['countryCode'])) { + $country_info = $this->model_extension_payment_paypal->getCountryByCode($payment_data['shippingContact']['countryCode']); + + if ($country_info) { + $this->session->data['shipping_address']['country'] = $country_info['name']; + $this->session->data['shipping_address']['country_id'] = $country_info['country_id']; + } + } + } + } - $json['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); + if ($payment_type == 'button') { + $this->session->data['payment_method'] = array( + 'code' => 'paypal', + 'title' => $this->language->get('text_paypal_title'), + 'terms' => '', + 'sort_order' => $this->config->get('payment_paypal_sort_order') + ); + } + + if ($payment_type == 'googlepay_button') { + $this->session->data['payment_method'] = array( + 'code' => 'paypal_googlepay', + 'title' => $this->language->get('text_paypal_googlepay_title'), + 'terms' => '', + 'sort_order' => $this->config->get('payment_paypal_sort_order') + ); + } + + if ($payment_type == 'applepay_button') { + $this->session->data['payment_method'] = array( + 'code' => 'paypal_applepay', + 'title' => $this->language->get('text_paypal_applepay_title'), + 'terms' => '', + 'sort_order' => $this->config->get('payment_paypal_sort_order') + ); + } + + $data['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); } } else { - if ((($payment_type == 'button') || ($payment_type == 'googlepay_button') || ($payment_type == 'applepay_button')) && !empty($this->request->post['paypal_order_id'])) { - $paypal_order_id = (int)$this->request->post['paypal_order_id']; + if (!empty($this->request->post['paypal_order_id'])) { + $paypal_order_id = $this->request->post['paypal_order_id']; } - - if (($payment_type == 'card') && !empty($this->request->post['payload'])) { - $payload = json_decode(htmlspecialchars_decode($this->request->post['payload']), true); - - if (isset($payload['orderId'])) { - $paypal_order_id = $payload['orderId']; - - if ($setting['card']['secure_status']) { - $paypal_order_info = $paypal->getOrder($paypal_order_id); - - if ($paypal->hasErrors()) { - $error_messages = []; - - $errors = $paypal->getErrors(); - - foreach ($errors as $error) { - if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { - $error['message'] = $this->language->get('error_timeout'); - } - - if (isset($error['details'][0]['description'])) { - $error_messages[] = $error['details'][0]['description']; - } elseif (isset($error['message'])) { - $error_messages[] = $error['message']; - } - - $this->model_extension_payment_paypal->log($error, $error['message']); - } - - $this->error['warning'] = implode(' ', $error_messages); + + if (($payment_type == 'card') && !empty($paypal_order_id)) { + $paypal_order_info = $paypal->getOrder($paypal_order_id); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); } - - if (isset($paypal_order_info['payment_source']['card']) && !$this->error) { - $this->model_extension_payment_paypal->log($paypal_order_info['payment_source']['card'], 'Card'); - - $liability_shift = ($paypal_order_info['payment_source']['card']['authentication_result']['liability_shift'] ?? ''); - $enrollment_status = ($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['enrollment_status'] ?? ''); - $authentication_status = ($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['authentication_status'] ?? ''); - - if ($enrollment_status == 'Y') { - if (($authentication_status == 'N') && !$setting['card']['secure_scenario']['failed_authentication']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['failed_authentication']['error']); - } - - if (($authentication_status == 'R') && !$setting['card']['secure_scenario']['rejected_authentication']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['rejected_authentication']['error']); - } - - if (($authentication_status == 'A') && !$setting['card']['secure_scenario']['attempted_authentication']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['attempted_authentication']['error']); - } - - if (($authentication_status == 'U') && !$setting['card']['secure_scenario']['unable_authentication']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['unable_authentication']['error']); - } - - if (($authentication_status == 'C') && !$setting['card']['secure_scenario']['challenge_authentication']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['challenge_authentication']['error']); - } - } - - if (($enrollment_status == 'N') && !$setting['card']['secure_scenario']['card_ineligible']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['card_ineligible']['error']); - } - - if (($enrollment_status == 'U') && !$setting['card']['secure_scenario']['system_unavailable']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_unavailable']['error']); - } - - if (($enrollment_status == 'B') && !$setting['card']['secure_scenario']['system_bypassed']) { - $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_bypassed']['error']); - } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; } - - if (!empty($this->error['warning'])) { - $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($paypal_order_info['payment_source']['card']) && !$this->error) { + $this->model_extension_payment_paypal->log($paypal_order_info['payment_source']['card'], 'Card'); + + $liability_shift = (isset($paypal_order_info['payment_source']['card']['authentication_result']['liability_shift']) ? $paypal_order_info['payment_source']['card']['authentication_result']['liability_shift'] : ''); + $enrollment_status = (isset($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['enrollment_status']) ? $paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['enrollment_status'] : ''); + $authentication_status = (isset($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['authentication_status']) ? $paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['authentication_status'] : ''); + + if ($enrollment_status == 'Y') { + if (($authentication_status == 'N') && !$setting['card']['secure_scenario']['failed_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['failed_authentication']['error']); + } + + if (($authentication_status == 'R') && !$setting['card']['secure_scenario']['rejected_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['rejected_authentication']['error']); } + + if (($authentication_status == 'A') && !$setting['card']['secure_scenario']['attempted_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['attempted_authentication']['error']); + } + + if (($authentication_status == 'U') && !$setting['card']['secure_scenario']['unable_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['unable_authentication']['error']); + } + + if (($authentication_status == 'C') && !$setting['card']['secure_scenario']['challenge_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['challenge_authentication']['error']); + } + } + + if (($enrollment_status == 'N') && !$setting['card']['secure_scenario']['card_ineligible']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['card_ineligible']['error']); } + + if (($enrollment_status == 'U') && !$setting['card']['secure_scenario']['system_unavailable']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_unavailable']['error']); + } + + if (($enrollment_status == 'B') && !$setting['card']['secure_scenario']['system_bypassed']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_bypassed']['error']); + } + } + + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } } - if (isset($paypal_order_id) && !$this->error) { + if (!empty($paypal_order_id) && !$this->error) { if ($transaction_method == 'authorize') { $result = $paypal->setOrderAuthorize($paypal_order_id); } else { $result = $paypal->setOrderCapture($paypal_order_id); } - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['details'][0]['issue']) && ($error['details'][0]['issue'] == 'INSTRUMENT_DECLINED')) { - $json['restart'] = true; + $data['restart'] = true; } - + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } - - if (!$this->error) { + + if (!$this->error) { $this->load->model('checkout/order'); - + $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - + if ($transaction_method == 'authorize') { $this->model_extension_payment_paypal->log($result, 'Authorize Order'); - + if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { $authorization_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; $authorization_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; - $seller_protection_status = $result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status']; + $seller_protection_status = $result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status']; $order_status_id = 0; $transaction_status = ''; $payment_method = ''; $vault_id = ''; $vault_customer_id = ''; - $paypal_order_data = []; - + $card_type = (!empty($this->request->post['card_type']) ? $this->request->post['card_type'] : ''); + $card_nice_type = (!empty($this->request->post['card_nice_type']) ? $this->request->post['card_nice_type'] : ''); + $card_last_digits = ''; + $card_expiry = ''; + if (!$this->cart->hasShipping()) { $seller_protection_status = 'NOT_ELIGIBLE'; } - + foreach ($result['payment_source'] as $payment_source_key => $payment_source) { - $vault_id = ($payment_source['attributes']['vault']['id'] ?? ''); - $vault_customer_id = ($payment_source['attributes']['vault']['customer']['id'] ?? ''); $payment_method = $payment_source_key; - + $vault_id = (isset($payment_source['attributes']['vault']['id']) ? $payment_source['attributes']['vault']['id'] : ''); + $vault_customer_id = (isset($payment_source['attributes']['vault']['customer']['id']) ? $payment_source['attributes']['vault']['customer']['id'] : ''); + $card_last_digits = (isset($payment_source['last_digits']) ? $payment_source['last_digits'] : ''); + $card_expiry = (isset($payment_source['expiry']) ? $payment_source['expiry'] : ''); + break; } @@ -1296,121 +1657,103 @@ public function approveOrder(): void { if ($authorization_status == 'CAPTURED') { $this->error['warning'] = sprintf($this->language->get('error_authorization_captured'), $this->url->link('information/contact', '', true)); } - + if ($authorization_status == 'DENIED') { $order_status_id = $setting['order_status']['denied']['id']; $transaction_status = 'denied'; - + $this->error['warning'] = $this->language->get('error_authorization_denied'); } - + if ($authorization_status == 'EXPIRED') { $this->error['warning'] = sprintf($this->language->get('error_authorization_expired'), $this->url->link('information/contact', '', true)); } - + if ($authorization_status == 'PENDING') { $order_status_id = $setting['order_status']['pending']['id']; $transaction_status = 'pending'; } - + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); - - $this->model_checkout_order->addHistory($this->session->data['order_id'], $order_status_id, $message); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); } - + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { + if ($payment_method == 'paypal') { + $paypal_customer_token = array(); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), $payment_method); + } + + if (!empty($paypal_customer_token['vault_id'])) { + $vault_id = $paypal_customer_token['vault_id']; + $vault_customer_id = $paypal_customer_token['vault_customer_id']; + } + } + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); - - $paypal_order_data = [ - 'order_id' => $this->session->data['order_id'], - 'transaction_id' => $authorization_id, + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $authorization_id, 'transaction_status' => $transaction_status, - 'payment_method' => $payment_method, - 'vault_id' => $vault_id, - 'vault_customer_id' => $vault_customer_id, - 'environment' => $environment - ]; + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_info['total'], + 'currency_code' => $order_info['currency_code'], + 'environment' => $environment + ); $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); - } - - if (($authorization_status == 'CREATED') || ($authorization_status == 'PENDING')) { - $this->load->model('checkout/subscription'); - - $subscription_products = $this->cart->getSubscriptions(); - - $order_products = $this->model_checkout_order->getProducts($this->session->data['order_id']); - - if (isset($this->request->server['HTTP_X_REAL_IP'])) { - $ip = $this->request->server['HTTP_X_REAL_IP']; - } elseif (oc_get_ip()) { - $ip = oc_get_ip(); - } else { - $ip = ''; - } - - if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { - $forwarded_ip = $this->request->server['HTTP_X_FORWARDED_FOR']; - } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { - $forwarded_ip = $this->request->server['HTTP_CLIENT_IP']; - } else { - $forwarded_ip = ''; - } - - if (isset($this->request->server['HTTP_USER_AGENT'])) { - $user_agent = $this->request->server['HTTP_USER_AGENT']; - } else { - $user_agent = ''; - } - - if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { - $accept_language = $this->request->server['HTTP_ACCEPT_LANGUAGE']; - } else { - $accept_language = ''; - } - - foreach ($subscription_products as $item) { - foreach ($order_products as $order_product) { - $subscription_info = $this->model_checkout_subscription->getSubscriptionByOrderProductId($this->session->data['order_id'], $order_product['order_product_id']); - - if ($subscription_info && $order_product['product_id'] == $item['product_id'] && $item['product_id'] == $subscription_info['product_id']) { - $item['subscription']['subscription_id'] = $subscription_info['subscription_id']; - $item['subscription']['order_product_id'] = $order_product['order_product_id']; - $item['subscription']['name'] = $item['name']; - $item['subscription']['product_id'] = $item['product_id']; - $item['subscription']['tax'] = $this->tax->getTax($item['price'], $item['tax_class_id']); - $item['subscription']['quantity'] = $item['quantity']; - $item['subscription']['store_id'] = (int)$this->config->get('config_store_id'); - $item['subscription']['customer_id'] = $this->customer->getId(); - $item['subscription']['payment_address_id'] = $subscription_info['payment_address_id']; - $item['subscription']['payment_method'] = $subscription_info['payment_method']; - $item['subscription']['shipping_address_id'] = $subscription_info['shipping_address_id']; - $item['subscription']['shipping_method'] = $subscription_info['shipping_method']; - $item['subscription']['comment'] = $subscription_info['comment']; - $item['subscription']['affiliate_id'] = $subscription_info['affiliate_id']; - $item['subscription']['marketing_id'] = $subscription_info['marketing_id']; - $item['subscription']['tracking'] = $subscription_info['tracking']; - $item['subscription']['language_id'] = $this->config->get('config_language_id'); - $item['subscription']['currency_id'] = $subscription_info['currency_id']; - $item['subscription']['ip'] = $ip; - $item['subscription']['forwarded_ip'] = $forwarded_ip; - $item['subscription']['user_agent'] = $user_agent; - $item['subscription']['accept_language'] = $accept_language; - - $this->model_extension_payment_paypal->subscriptionPayment($item, $order_info, $paypal_order_data); - } + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); } } - + + if (($authorization_status == 'CREATED') || ($authorization_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_info, $paypal_order_data); + } + } + if (($authorization_status == 'CREATED') || ($authorization_status == 'PARTIALLY_CAPTURED') || ($authorization_status == 'PARTIALLY_CREATED') || ($authorization_status == 'VOIDED') || ($authorization_status == 'PENDING')) { - $json['url'] = $this->url->link('checkout/success', '', true); + $data['url'] = $this->url->link('checkout/success', '', true); } } } else { $this->model_extension_payment_paypal->log($result, 'Capture Order'); - + if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { $capture_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; $capture_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; @@ -1420,133 +1763,121 @@ public function approveOrder(): void { $payment_method = ''; $vault_id = ''; $vault_customer_id = ''; - $paypal_order_data = []; - + $card_type = (!empty($this->request->post['card_type']) ? $this->request->post['card_type'] : ''); + $card_nice_type = (!empty($this->request->post['card_nice_type']) ? $this->request->post['card_nice_type'] : ''); + $card_last_digits = ''; + $card_expiry = ''; + if (!$this->cart->hasShipping()) { $seller_protection_status = 'NOT_ELIGIBLE'; } - + foreach ($result['payment_source'] as $payment_source_key => $payment_source) { - $vault_id = ($payment_source['attributes']['vault']['id'] ?? ''); - $vault_customer_id = ($payment_source['attributes']['vault']['customer']['id'] ?? ''); $payment_method = $payment_source_key; - + $vault_id = (isset($payment_source['attributes']['vault']['id']) ? $payment_source['attributes']['vault']['id'] : ''); + $vault_customer_id = (isset($payment_source['attributes']['vault']['customer']['id']) ? $payment_source['attributes']['vault']['customer']['id'] : ''); + $card_last_digits = (isset($payment_source['last_digits']) ? $payment_source['last_digits'] : ''); + $card_expiry = (isset($payment_source['expiry']) ? $payment_source['expiry'] : ''); + break; } - + if ($capture_status == 'COMPLETED') { $order_status_id = $setting['order_status']['completed']['id']; $transaction_status = 'completed'; } - + if ($capture_status == 'DECLINED') { $order_status_id = $setting['order_status']['denied']['id']; $transaction_status = 'denied'; - + $this->error['warning'] = $this->language->get('error_capture_declined'); } - + if ($capture_status == 'FAILED') { $this->error['warning'] = sprintf($this->language->get('error_capture_failed'), $this->url->link('information/contact', '', true)); } - + if ($capture_status == 'PENDING') { $order_status_id = $setting['order_status']['pending']['id']; $transaction_status = 'pending'; } - + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); - - $this->model_checkout_order->addHistory($this->session->data['order_id'], $order_status_id, $message); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); } - + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { + if ($payment_method == 'paypal') { + $paypal_customer_token = array(); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), $payment_method); + } + + if (!empty($paypal_customer_token['vault_id'])) { + $vault_id = $paypal_customer_token['vault_id']; + $vault_customer_id = $paypal_customer_token['vault_customer_id']; + } + } + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); - - $paypal_order_data = [ - 'order_id' => $this->session->data['order_id'], - 'transaction_id' => $capture_id, + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $capture_id, 'transaction_status' => $transaction_status, - 'payment_method' => $payment_method, - 'vault_id' => $vault_id, - 'vault_customer_id' => $vault_customer_id, - 'environment' => $environment - ]; + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_info['total'], + 'currency_code' => $order_info['currency_code'], + 'environment' => $environment + ); $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); - } - - if (($capture_status == 'COMPLETED') || ($capture_status == 'PENDING')) { - // Loop through any products that are subscription items - $subscription_products = $this->cart->getSubscriptions(); - - $order_products = $this->model_checkout_order->getProducts($this->session->data['order_id']); - - if (isset($this->request->server['HTTP_X_REAL_IP'])) { - $ip = $this->request->server['HTTP_X_REAL_IP']; - } elseif (oc_get_ip()) { - $ip = oc_get_ip(); - } else { - $ip = ''; - } - - if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { - $forwarded_ip = $this->request->server['HTTP_X_FORWARDED_FOR']; - } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { - $forwarded_ip = $this->request->server['HTTP_CLIENT_IP']; - } else { - $forwarded_ip = ''; - } - - if (isset($this->request->server['HTTP_USER_AGENT'])) { - $user_agent = $this->request->server['HTTP_USER_AGENT']; - } else { - $user_agent = ''; - } - - if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { - $accept_language = $this->request->server['HTTP_ACCEPT_LANGUAGE']; - } else { - $accept_language = ''; - } - - foreach ($subscription_products as $item) { - foreach ($order_products as $order_product) { - $subscription_info = $this->model_checkout_subscription->getSubscriptionByOrderProductId($this->session->data['order_id'], $order_product['order_product_id']); - - if ($subscription_info && $order_product['product_id'] == $item['product_id'] && $item['product_id'] == $subscription_info['product_id']) { - $item['subscription']['subscription_id'] = $subscription_info['subscription_id']; - $item['subscription']['order_product_id'] = $order_product['order_product_id']; - $item['subscription']['name'] = $item['name']; - $item['subscription']['product_id'] = $item['product_id']; - $item['subscription']['tax'] = $this->tax->getTax($item['price'], $item['tax_class_id']); - $item['subscription']['quantity'] = $item['quantity']; - $item['subscription']['store_id'] = (int)$this->config->get('config_store_id'); - $item['subscription']['customer_id'] = $this->customer->getId(); - $item['subscription']['payment_address_id'] = $subscription_info['payment_address_id']; - $item['subscription']['payment_method'] = $subscription_info['payment_method']; - $item['subscription']['shipping_address_id'] = $subscription_info['shipping_address_id']; - $item['subscription']['shipping_method'] = $subscription_info['shipping_method']; - $item['subscription']['comment'] = $subscription_info['comment']; - $item['subscription']['affiliate_id'] = $subscription_info['affiliate_id']; - $item['subscription']['marketing_id'] = $subscription_info['marketing_id']; - $item['subscription']['tracking'] = $subscription_info['tracking']; - $item['subscription']['language_id'] = $this->config->get('config_language_id'); - $item['subscription']['currency_id'] = $subscription_info['currency_id']; - $item['subscription']['ip'] = $ip; - $item['subscription']['forwarded_ip'] = $forwarded_ip; - $item['subscription']['user_agent'] = $user_agent; - $item['subscription']['accept_language'] = $accept_language; - - $this->model_extension_payment_paypal->subscriptionPayment($item, $order_info, $paypal_order_data); - } + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); } } - + + if (($capture_status == 'COMPLETED') || ($capture_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_info, $paypal_order_data); + } + } + if (($capture_status == 'COMPLETED') || ($capture_status == 'PARTIALLY_REFUNDED') || ($capture_status == 'REFUNDED') || ($capture_status == 'PENDING')) { - $json['url'] = $this->url->link('checkout/success', '', true); + $data['url'] = $this->url->link('checkout/success', '', true); } } } @@ -1555,27 +1886,22 @@ public function approveOrder(): void { } } - $json['error'] = $this->error; - + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Confirm Order - * - * @return void - */ - public function confirmOrder(): void { + + public function confirmOrder() { $this->load->language('extension/payment/paypal'); $this->load->language('checkout/cart'); $this->load->model('tool/image'); - + if (!isset($this->session->data['paypal_order_id'])) { $this->response->redirect($this->url->link('checkout/cart', '', true)); } - + // Coupon if (isset($this->request->post['coupon']) && $this->validateCoupon()) { $this->session->data['coupon'] = $this->request->post['coupon']; @@ -1602,32 +1928,40 @@ public function confirmOrder(): void { $this->response->redirect($this->url->link('extension/payment/paypal/confirmOrder', '', true)); } - + $this->document->setTitle($this->language->get('text_paypal')); - + $this->document->addScript('catalog/view/javascript/jquery/datetimepicker/moment/moment.min.js'); $this->document->addScript('catalog/view/javascript/jquery/datetimepicker/moment/moment-with-locales.min.js'); $this->document->addScript('catalog/view/javascript/jquery/datetimepicker/bootstrap-datetimepicker.min.js'); $this->document->addStyle('catalog/view/javascript/jquery/datetimepicker/bootstrap-datetimepicker.min.css'); + + $theme = $this->config->get('theme_' . $this->config->get('config_theme') . '_directory'); + + if (file_exists(DIR_TEMPLATE . $theme . '/stylesheet/paypal/paypal.css')) { + $this->document->addStyle('catalog/view/theme/' . $theme . '/stylesheet/paypal/paypal.css'); + } else { + $this->document->addStyle('catalog/view/theme/default/stylesheet/paypal/paypal.css'); + } $data['heading_title'] = $this->language->get('text_paypal'); - $data['breadcrumbs'] = []; + $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/home', '', true) - ]; - - $data['breadcrumbs'][] = [ + ); + + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_cart'), 'href' => $this->url->link('checkout/cart', '', true) - ]; + ); - $data['breadcrumbs'][] = [ + $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_paypal'), 'href' => $this->url->link('extension/payment/paypal/confirmOrder', '', true) - ]; + ); $points_total = 0; @@ -1636,7 +1970,7 @@ public function confirmOrder(): void { $points_total += $product['points']; } } - + if (isset($this->request->post['next'])) { $data['next'] = $this->request->post['next']; } else { @@ -1644,13 +1978,13 @@ public function confirmOrder(): void { } $this->load->model('tool/upload'); - + if (!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) { $this->response->redirect($this->url->link('checkout/cart', '', true)); } - - $data['products'] = []; - + + $data['products'] = array(); + $products = $this->cart->getProducts(); foreach ($products as $product) { @@ -1672,7 +2006,7 @@ public function confirmOrder(): void { $image = ''; } - $option_data = []; + $option_data = array(); foreach ($product['option'] as $option) { if ($option['type'] != 'file') { @@ -1687,10 +2021,10 @@ public function confirmOrder(): void { } } - $option_data[] = [ + $option_data[] = array( 'name' => $option['name'], - 'value' => (oc_strlen($value) > 20 ? oc_substr($value, 0, 20) . '..' : $value) - ]; + 'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value) + ); } // Display prices @@ -1703,17 +2037,17 @@ public function confirmOrder(): void { $price = false; $total = false; } - + $recurring = ''; if ($product['recurring']) { - $frequencies = [ + $frequencies = array( 'day' => $this->language->get('text_day'), 'week' => $this->language->get('text_week'), 'semi_month' => $this->language->get('text_semi_month'), 'month' => $this->language->get('text_month'), 'year' => $this->language->get('text_year'), - ]; + ); if ($product['recurring']['trial']) { $recurring = sprintf($this->language->get('text_trial_description'), $this->currency->format($this->tax->calculate($product['recurring']['trial_price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), $product['recurring']['trial_cycle'], $frequencies[$product['recurring']['trial_frequency']], $product['recurring']['trial_duration']) . ' '; @@ -1726,95 +2060,125 @@ public function confirmOrder(): void { } } - $data['products'][] = [ - 'cart_id' => $product['cart_id'], - 'thumb' => $image, - 'name' => $product['name'], - 'model' => $product['model'], - 'option' => $option_data, - 'recurring' => $recurring, - 'quantity' => $product['quantity'], - 'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')), - 'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''), - 'price' => $price, - 'total' => $total, - 'href' => $this->url->link('product/product', 'product_id=' . $product['product_id'], true) - ]; + $data['products'][] = array( + 'cart_id' => $product['cart_id'], + 'thumb' => $image, + 'name' => $product['name'], + 'model' => $product['model'], + 'option' => $option_data, + 'recurring' => $recurring, + 'quantity' => $product['quantity'], + 'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')), + 'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''), + 'price' => $price, + 'total' => $total, + 'href' => $this->url->link('product/product', 'product_id=' . $product['product_id'], true) + ); } // Gift Voucher - $data['vouchers'] = []; + $data['vouchers'] = array(); if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $key => $voucher) { - $data['vouchers'][] = [ + $data['vouchers'][] = array( 'key' => $key, 'description' => $voucher['description'], 'amount' => $this->currency->format($voucher['amount'], $this->session->data['currency']), 'remove' => $this->url->link('checkout/cart', 'remove=' . $key, true) - ]; + ); } } - + $this->load->model('setting/extension'); - + if ($this->cart->hasShipping()) { $data['has_shipping'] = true; + + $data['shipping_address'] = isset($this->session->data['shipping_address']) ? $this->session->data['shipping_address'] : array(); + + if (!empty($data['shipping_address'])) { + // Shipping Methods + $quote_data = array(); + + $results = $this->model_setting_extension->getExtensions('shipping'); + + if (!empty($results)) { + foreach ($results as $result) { + if ($this->config->get('shipping_' . $result['code'] . '_status')) { + $this->load->model('extension/shipping/' . $result['code']); + + $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($data['shipping_address']); + + if ($quote) { + $quote_data[$result['code']] = array( + 'title' => $quote['title'], + 'quote' => $quote['quote'], + 'sort_order' => $quote['sort_order'], + 'error' => $quote['error'] + ); + } + } + } - $data['shipping_address'] = $this->session->data['shipping_address'] ?? []; + if (!empty($quote_data)) { + $sort_order = array(); - if ($data['shipping_address']) { - // Shipping methods - $this->load->model('checkout/shipping_method'); + foreach ($quote_data as $key => $value) { + $sort_order[$key] = $value['sort_order']; + } - $quote_data = $this->model_checkout_shipping_method->getMethods($this->session->data['shipping_address']); + array_multisort($sort_order, SORT_ASC, $quote_data); - if ($quote_data) { - $data['shipping_methods'] = $this->session->data['shipping_methods'] = $quote_data; + $this->session->data['shipping_methods'] = $quote_data; + $data['shipping_methods'] = $quote_data; - if (!isset($this->session->data['shipping_method'])) { - // Default the shipping to the very first option. - $key1 = key($quote_data); - $key2 = key($quote_data[$key1]['quote']); + if (!isset($this->session->data['shipping_method'])) { + //default the shipping to the very first option. + $key1 = key($quote_data); + $key2 = key($quote_data[$key1]['quote']); + $this->session->data['shipping_method'] = $quote_data[$key1]['quote'][$key2]; + } - $this->session->data['shipping_method'] = $quote_data[$key1]['quote'][$key2]; + $data['shipping_method_code'] = $this->session->data['shipping_method']['code']; + $data['action_shipping'] = $this->url->link('extension/payment/paypal/confirmShipping', '', true); + } else { + unset($this->session->data['shipping_methods']); + unset($this->session->data['shipping_method']); + + $data['error_no_shipping'] = $this->language->get('error_no_shipping'); } - - $data['code'] = $this->session->data['shipping_method']['code']; - - $data['action_shipping'] = $this->url->link('extension/module/paypal_smart_button/confirmShipping', '', true); } else { unset($this->session->data['shipping_methods']); unset($this->session->data['shipping_method']); - + $data['error_no_shipping'] = $this->language->get('error_no_shipping'); } } } else { $data['has_shipping'] = false; } - - $data['guest'] = $this->session->data['guest'] ?? []; - - $data['payment_address'] = $this->session->data['payment_address'] ?? []; - + + $data['guest'] = isset($this->session->data['guest']) ? $this->session->data['guest'] : array(); + $data['payment_address'] = isset($this->session->data['payment_address']) ? $this->session->data['payment_address'] : array(); + // Totals - $totals = []; + $totals = array(); $taxes = $this->cart->getTaxes(); $total = 0; // Because __call can not keep var references so we put them into an array. - $total_data = [ + $total_data = array( 'totals' => &$totals, 'taxes' => &$taxes, 'total' => &$total - ]; + ); // Display prices if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) { - $sort_order = []; + $sort_order = array(); - $results = $this->model_setting_extension->getExtensionsByType('total'); + $results = $this->model_setting_extension->getExtensions('total'); foreach ($results as $key => $value) { $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); @@ -1831,7 +2195,7 @@ public function confirmOrder(): void { } } - $sort_order = []; + $sort_order = array(); foreach ($totals as $key => $value) { $sort_order[$key] = $value['sort_order']; @@ -1839,51 +2203,73 @@ public function confirmOrder(): void { array_multisort($sort_order, SORT_ASC, $totals); } - + /** * Payment methods */ - $results = $this->model_setting_extension->getExtensionsByType('payment'); + $method_data = array(); - $this->load->model('checkout/payment_method'); + $results = $this->model_setting_extension->getExtensions('payment'); - $method_data = $this->model_checkout_payment_method->getMethods($this->session->data['payment_address']); + foreach ($results as $result) { + if ($this->config->get('payment_' . $result['code'] . '_status')) { + $this->load->model('extension/payment/' . $result['code']); - $this->session->data['payment_methods'] = $method_data; + $method = $this->{'model_extension_payment_' . $result['code']}->getMethod($data['payment_address'], $total); - $data['payment_methods'] = $method_data; + if ($method) { + $method_data[$result['code']] = $method; + } + } + } - if (!isset($method_data['paypal'])) { - $this->session->data['error_warning'] = $this->language->get('error_unavailable'); + $sort_order = array(); - $this->response->redirect($this->url->link('checkout/checkout', '', true)); + foreach ($method_data as $key => $value) { + $sort_order[$key] = $value['sort_order']; } + array_multisort($sort_order, SORT_ASC, $method_data); + $this->session->data['payment_methods'] = $method_data; - $this->session->data['payment_method'] = $method_data['paypal']; + $data['payment_methods'] = $method_data; + if (!isset($method_data['paypal'])) { + $this->session->data['error_warning'] = $this->language->get('error_unavailable'); + + $this->response->redirect($this->url->link('checkout/checkout', '', true)); + } + + if (isset($this->session->data['payment_method']['code'])) { + $data['payment_method_code'] = $this->session->data['payment_method']['code']; + } else { + $this->session->data['payment_method'] = $method_data['paypal']; + + $data['payment_method_code'] = $this->session->data['payment_method']['code']; + } + // Custom Fields $this->load->model('account/custom_field'); $data['custom_fields'] = $this->model_account_custom_field->getCustomFields(); // Totals - $totals = []; + $totals = array(); $taxes = $this->cart->getTaxes(); $total = 0; // Because __call can not keep var references so we put them into an array. - $total_data = [ + $total_data = array( 'totals' => &$totals, 'taxes' => &$taxes, 'total' => &$total - ]; + ); // Display prices if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) { - $sort_order = []; + $sort_order = array(); - $results = $this->model_setting_extension->getExtensionsByType('total'); + $results = $this->model_setting_extension->getExtensions('total'); foreach ($results as $key => $value) { $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); @@ -1900,7 +2286,7 @@ public function confirmOrder(): void { } } - $sort_order = []; + $sort_order = array(); foreach ($totals as $key => $value) { $sort_order[$key] = $value['sort_order']; @@ -1909,13 +2295,13 @@ public function confirmOrder(): void { array_multisort($sort_order, SORT_ASC, $totals); } - $data['totals'] = []; + $data['totals'] = array(); foreach ($totals as $total) { - $data['totals'][] = [ + $data['totals'][] = array( 'title' => $total['title'], 'text' => $this->currency->format($total['value'], $this->session->data['currency']), - ]; + ); } $data['action_confirm'] = $this->url->link('extension/payment/paypal/completeOrder', '', true); @@ -1953,17 +2339,12 @@ public function confirmOrder(): void { $this->response->setOutput($this->load->view('extension/payment/paypal/confirm', $data)); } - - /** - * Complete Order - * - * @return void - */ - public function completeOrder(): void { + + public function completeOrder() { $this->load->language('extension/payment/paypal'); - + $this->load->model('extension/payment/paypal'); - + // Validate if payment address has been set. if (empty($this->session->data['payment_address'])) { $this->response->redirect($this->url->link('checkout/checkout', '', true)); @@ -1973,7 +2354,7 @@ public function completeOrder(): void { if (!isset($this->session->data['payment_method'])) { $this->response->redirect($this->url->link('checkout/checkout', '', true)); } - + if ($this->cart->hasShipping()) { // Validate if shipping address has been set. if (empty($this->session->data['shipping_address'])) { @@ -1993,26 +2374,26 @@ public function completeOrder(): void { if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { $this->response->redirect($this->url->link('checkout/cart', '', true)); } + + if (isset($this->session->data['paypal_order_id'])) { + $order_data = array(); - if (isset($this->session->data['paypal_order_id'])) { - $order_data = []; - - $totals = []; + $totals = array(); $taxes = $this->cart->getTaxes(); $total = 0; // Because __call can not keep var references so we put them into an array. - $total_data = [ + $total_data = array( 'totals' => &$totals, 'taxes' => &$taxes, 'total' => &$total - ]; + ); $this->load->model('setting/extension'); - $sort_order = []; + $sort_order = array(); - $results = $this->model_setting_extension->getExtensionsByType('total'); + $results = $this->model_setting_extension->getExtensions('total'); foreach ($results as $key => $value) { $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); @@ -2029,18 +2410,18 @@ public function completeOrder(): void { } } - $sort_order = []; + $sort_order = array(); foreach ($totals as $key => $value) { $sort_order[$key] = $value['sort_order']; } array_multisort($sort_order, SORT_ASC, $totals); - + $order_data['totals'] = $totals; $order_data['invoice_prefix'] = $this->config->get('config_invoice_prefix'); - $order_data['store_id'] = (int)$this->config->get('config_store_id'); + $order_data['store_id'] = $this->config->get('config_store_id'); $order_data['store_name'] = $this->config->get('config_name'); if ($order_data['store_id']) { @@ -2052,15 +2433,20 @@ public function completeOrder(): void { $order_data['store_url'] = HTTP_SERVER; } } - + $order_data['customer_id'] = $this->session->data['guest']['customer_id']; $order_data['customer_group_id'] = $this->session->data['guest']['customer_group_id']; $order_data['firstname'] = $this->session->data['guest']['firstname']; $order_data['lastname'] = $this->session->data['guest']['lastname']; - $order_data['email'] = $this->session->data['guest']['email']; $order_data['telephone'] = $this->session->data['guest']['telephone']; $order_data['custom_field'] = $this->session->data['guest']['custom_field']; - + + if ($this->session->data['guest']['email']) { + $order_data['email'] = $this->session->data['guest']['email']; + } else { + $order_data['email'] = $this->config->get('config_email'); + } + $order_data['payment_firstname'] = $this->session->data['payment_address']['firstname']; $order_data['payment_lastname'] = $this->session->data['payment_address']['lastname']; $order_data['payment_company'] = $this->session->data['payment_address']['company']; @@ -2073,10 +2459,10 @@ public function completeOrder(): void { $order_data['payment_country'] = $this->session->data['payment_address']['country']; $order_data['payment_country_id'] = $this->session->data['payment_address']['country_id']; $order_data['payment_address_format'] = $this->session->data['payment_address']['address_format']; - $order_data['payment_custom_field'] = ($this->session->data['payment_address']['custom_field'] ?? []); + $order_data['payment_custom_field'] = (isset($this->session->data['payment_address']['custom_field']) ? $this->session->data['payment_address']['custom_field'] : array()); - if (isset($this->session->data['payment_method']['name'])) { - $order_data['payment_method'] = $this->session->data['payment_method']['name']; + if (isset($this->session->data['payment_method']['title'])) { + $order_data['payment_method'] = $this->session->data['payment_method']['title']; } else { $order_data['payment_method'] = ''; } @@ -2085,7 +2471,7 @@ public function completeOrder(): void { $order_data['payment_code'] = $this->session->data['payment_method']['code']; } else { $order_data['payment_code'] = ''; - } + } if ($this->cart->hasShipping()) { $order_data['shipping_firstname'] = $this->session->data['shipping_address']['firstname']; @@ -2100,7 +2486,7 @@ public function completeOrder(): void { $order_data['shipping_country'] = $this->session->data['shipping_address']['country']; $order_data['shipping_country_id'] = $this->session->data['shipping_address']['country_id']; $order_data['shipping_address_format'] = $this->session->data['shipping_address']['address_format']; - $order_data['shipping_custom_field'] = ($this->session->data['shipping_address']['custom_field'] ?? []); + $order_data['shipping_custom_field'] = (isset($this->session->data['shipping_address']['custom_field']) ? $this->session->data['shipping_address']['custom_field'] : array()); if (isset($this->session->data['shipping_method']['title'])) { $order_data['shipping_method'] = $this->session->data['shipping_method']['title']; @@ -2126,18 +2512,18 @@ public function completeOrder(): void { $order_data['shipping_country'] = ''; $order_data['shipping_country_id'] = 0; $order_data['shipping_address_format'] = ''; - $order_data['shipping_custom_field'] = []; + $order_data['shipping_custom_field'] = array(); $order_data['shipping_method'] = ''; $order_data['shipping_code'] = ''; } - $order_data['products'] = []; + $order_data['products'] = array(); foreach ($this->cart->getProducts() as $product) { - $option_data = []; + $option_data = array(); foreach ($product['option'] as $option) { - $option_data[] = [ + $option_data[] = array( 'product_option_id' => $option['product_option_id'], 'product_option_value_id' => $option['product_option_value_id'], 'option_id' => $option['option_id'], @@ -2145,10 +2531,10 @@ public function completeOrder(): void { 'name' => $option['name'], 'value' => $option['value'], 'type' => $option['type'] - ]; + ); } - $order_data['products'][] = [ + $order_data['products'][] = array( 'product_id' => $product['product_id'], 'name' => $product['name'], 'model' => $product['model'], @@ -2160,17 +2546,17 @@ public function completeOrder(): void { 'total' => $product['total'], 'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']), 'reward' => $product['reward'] - ]; + ); } // Gift Voucher - $order_data['vouchers'] = []; + $order_data['vouchers'] = array(); if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { - $order_data['vouchers'][] = [ + $order_data['vouchers'][] = array( 'description' => $voucher['description'], - 'code' => oc_token(10), + 'code' => token(10), 'to_name' => $voucher['to_name'], 'to_email' => $voucher['to_email'], 'from_name' => $voucher['from_name'], @@ -2178,11 +2564,11 @@ public function completeOrder(): void { 'voucher_theme_id' => $voucher['voucher_theme_id'], 'message' => $voucher['message'], 'amount' => $voucher['amount'] - ]; + ); } } - $order_data['comment'] = ($this->session->data['comment'] ?? ''); + $order_data['comment'] = (isset($this->session->data['comment']) ? $this->session->data['comment'] : ''); $order_data['total'] = $total_data['total']; if (isset($this->request->cookie['tracking'])) { @@ -2192,7 +2578,7 @@ public function completeOrder(): void { // Affiliate $this->load->model('account/customer'); - + $affiliate_info = $this->model_account_customer->getAffiliateByTracking($this->request->cookie['tracking']); if ($affiliate_info) { @@ -2224,7 +2610,7 @@ public function completeOrder(): void { $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'] = oc_get_ip(); + $order_data['ip'] = $this->request->server['REMOTE_ADDR']; if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { $order_data['forwarded_ip'] = $this->request->server['HTTP_X_FORWARDED_FOR']; @@ -2245,113 +2631,166 @@ public function completeOrder(): void { } else { $order_data['accept_language'] = ''; } - + $this->load->model('checkout/order'); $this->session->data['order_id'] = $this->model_checkout_order->addOrder($order_data); - + $order_data['order_id'] = $this->session->data['order_id']; - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $vault_status = $setting['general']['vault_status']; $transaction_method = $setting['general']['transaction_method']; - + $currency_code = $this->session->data['currency']; $currency_value = $this->currency->getValue($this->session->data['currency']); - + if (empty($setting['currency'][$currency_code]['status'])) { $currency_code = $setting['general']['currency_code']; $currency_value = $setting['general']['currency_value']; } - + $decimal_place = $setting['currency'][$currency_code]['decimal_place']; - + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $paypal_order_id = $this->session->data['paypal_order_id']; - - $paypal_order_info = []; - - $paypal_order_info[] = [ - 'op' => 'add', - 'path' => '/purchase_units/@reference_id == \'default\'/description', + + $paypal_order_info = $paypal->getOrder($paypal_order_id); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + } + + $shipping_info_name = array(); + $shipping_info_address = array(); + + if ($paypal_order_info && !$this->error) { + $shipping_info_name = (isset($paypal_order_info['purchase_units'][0]['shipping']['name']) ? $paypal_order_info['purchase_units'][0]['shipping']['name'] : array()); + $shipping_info_address = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']) ? $paypal_order_info['purchase_units'][0]['shipping']['address'] : array()); + } + + $paypal_order_info = array(); + + $paypal_order_info[] = array( + 'op' => 'add', + 'path' => '/purchase_units/@reference_id==\'default\'/description', 'value' => 'Your order ' . $this->session->data['order_id'] - ]; - - $paypal_order_info[] = [ - 'op' => 'add', - 'path' => '/purchase_units/@reference_id == \'default\'/invoice_id', + ); + + $paypal_order_info[] = array( + 'op' => 'add', + 'path' => '/purchase_units/@reference_id==\'default\'/invoice_id', 'value' => $this->session->data['order_id'] . '_' . date('Ymd_His') - ]; - - $shipping_info = []; + ); + + $shipping_info = array(); if ($this->cart->hasShipping()) { - $shipping_info['name']['full_name'] = ($this->session->data['shipping_address']['firstname'] ?? ''); - $shipping_info['name']['full_name'] .= (isset($this->session->data['shipping_address']['lastname']) ? (' ' . $this->session->data['shipping_address']['lastname']) : ''); - $shipping_info['address']['address_line_1'] = ($this->session->data['shipping_address']['address_1'] ?? ''); - $shipping_info['address']['address_line_2'] = ($this->session->data['shipping_address']['address_2'] ?? ''); - $shipping_info['address']['admin_area_1'] = ($this->session->data['shipping_address']['zone'] ?? ''); - $shipping_info['address']['admin_area_2'] = ($this->session->data['shipping_address']['city'] ?? ''); - $shipping_info['address']['postal_code'] = ($this->session->data['shipping_address']['postcode'] ?? ''); - + $shipping_info['name']['full_name'] = (isset($this->session->data['shipping_address']['firstname']) ? $this->session->data['shipping_address']['firstname'] : ''); + $shipping_info['name']['full_name'] .= (isset($this->session->data['shipping_address']['lastname']) ? (' ' . $this->session->data['shipping_address']['lastname']) : ''); + $shipping_info['address']['address_line_1'] = (isset($this->session->data['shipping_address']['address_1']) ? $this->session->data['shipping_address']['address_1'] : ''); + $shipping_info['address']['address_line_2'] = (isset($this->session->data['shipping_address']['address_2']) ? $this->session->data['shipping_address']['address_2'] : ''); + $shipping_info['address']['admin_area_1'] = (isset($this->session->data['shipping_address']['zone']) ? $this->session->data['shipping_address']['zone'] : ''); + $shipping_info['address']['admin_area_2'] = (isset($this->session->data['shipping_address']['city']) ? $this->session->data['shipping_address']['city'] : ''); + $shipping_info['address']['postal_code'] = (isset($this->session->data['shipping_address']['postcode']) ? $this->session->data['shipping_address']['postcode'] : ''); + if (isset($this->session->data['shipping_address']['country_id'])) { $this->load->model('localisation/country'); - + $country_info = $this->model_localisation_country->getCountry($this->session->data['shipping_address']['country_id']); - + if ($country_info) { $shipping_info['address']['country_code'] = $country_info['iso_code_2']; } } - - $paypal_order_info[] = [ - 'op' => 'replace', - 'path' => '/purchase_units/@reference_id == \'default\'/shipping/name', - 'value' => $shipping_info['name'] - ]; - - $paypal_order_info[] = [ - 'op' => 'replace', - 'path' => '/purchase_units/@reference_id == \'default\'/shipping/address', - 'value' => $shipping_info['address'] - ]; + + if ($shipping_info_name) { + $paypal_order_info[] = array( + 'op' => 'replace', + 'path' => '/purchase_units/@reference_id==\'default\'/shipping/name', + 'value' => $shipping_info['name'] + ); + } else { + $paypal_order_info[] = array( + 'op' => 'add', + 'path' => '/purchase_units/@reference_id==\'default\'/shipping/name', + 'value' => $shipping_info['name'] + ); + } + + if ($shipping_info_address) { + $paypal_order_info[] = array( + 'op' => 'replace', + 'path' => '/purchase_units/@reference_id==\'default\'/shipping/address', + 'value' => $shipping_info['address'] + ); + } else { + $paypal_order_info[] = array( + 'op' => 'add', + 'path' => '/purchase_units/@reference_id==\'default\'/shipping/address', + 'value' => $shipping_info['address'] + ); + } } - + $item_total = 0; $tax_total = 0; - + foreach ($this->cart->getProducts() as $product) { $product_price = number_format($product['price'] * $currency_value, $decimal_place, '.', ''); - + $item_total += $product_price * $product['quantity']; - + if ($product['tax_class_id']) { $tax_rates = $this->tax->getRates($product['price'], $product['tax_class_id']); @@ -2360,160 +2799,165 @@ public function completeOrder(): void { } } } - + if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $item_total += $voucher['amount']; } } - + $item_total = number_format($item_total, $decimal_place, '.', ''); $tax_total = number_format($tax_total * $currency_value, $decimal_place, '.', ''); - + $discount_total = 0; $handling_total = 0; $shipping_total = 0; - + if (isset($this->session->data['shipping_method'])) { $shipping_total = $this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], true); $shipping_total = number_format($shipping_total * $currency_value, $decimal_place, '.', ''); } - + $order_total = number_format($order_data['total'] * $currency_value, $decimal_place, '.', ''); - + $rebate = number_format($item_total + $tax_total + $shipping_total - $order_total, $decimal_place, '.', ''); - + if ($rebate > 0) { $discount_total = $rebate; } elseif ($rebate < 0) { $handling_total = -$rebate; } - - $amount_info = []; - + + $amount_info = array(); + $amount_info['currency_code'] = $currency_code; $amount_info['value'] = $order_total; - - $amount_info['breakdown']['item_total'] = [ + + $amount_info['breakdown']['item_total'] = array( 'currency_code' => $currency_code, - 'value' => $item_total - ]; - - $amount_info['breakdown']['tax_total'] = [ + 'value' => $item_total + ); + + $amount_info['breakdown']['tax_total'] = array( 'currency_code' => $currency_code, - 'value' => $tax_total - ]; - - $amount_info['breakdown']['shipping'] = [ + 'value' => $tax_total + ); + + $amount_info['breakdown']['shipping'] = array( 'currency_code' => $currency_code, - 'value' => $shipping_total - ]; - - $amount_info['breakdown']['handling'] = [ + 'value' => $shipping_total + ); + + $amount_info['breakdown']['handling'] = array( 'currency_code' => $currency_code, - 'value' => $handling_total - ]; - - $amount_info['breakdown']['discount'] = [ + 'value' => $handling_total + ); + + $amount_info['breakdown']['discount'] = array( 'currency_code' => $currency_code, - 'value' => $discount_total - ]; - - $paypal_order_info[] = [ - 'op' => 'replace', - 'path' => '/purchase_units/@reference_id == \'default\'/amount', + 'value' => $discount_total + ); + + $paypal_order_info[] = array( + 'op' => 'replace', + 'path' => '/purchase_units/@reference_id==\'default\'/amount', 'value' => $amount_info - ]; - + ); + $result = $paypal->updateOrder($paypal_order_id, $paypal_order_info); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } - - if ($paypal_order_id && !$this->error) { + + if ($paypal_order_id && !$this->error) { if ($transaction_method == 'authorize') { $result = $paypal->setOrderAuthorize($paypal_order_id); } else { $result = $paypal->setOrderCapture($paypal_order_id); } - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['details'][0]['issue']) && ($error['details'][0]['issue'] == 'INSTRUMENT_DECLINED')) { $data['restart'] = true; } - + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } - + if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); } - - if (!$this->error) { + + if (!$this->error) { if ($transaction_method == 'authorize') { $this->model_extension_payment_paypal->log($result, 'Authorize Order'); - + if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { $authorization_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; $authorization_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; - $seller_protection_status = $result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status']; + $seller_protection_status = $result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status']; $order_status_id = 0; $transaction_status = ''; $payment_method = ''; $vault_id = ''; $vault_customer_id = ''; - $paypal_order_data = []; - + $card_type = ''; + $card_nice_type = ''; + $card_last_digits = ''; + $card_expiry = ''; + if (!$this->cart->hasShipping()) { $seller_protection_status = 'NOT_ELIGIBLE'; } - + foreach ($result['payment_source'] as $payment_source_key => $payment_source) { - $vault_id = ($payment_source['attributes']['vault']['id'] ?? ''); - $vault_customer_id = ($payment_source['attributes']['vault']['customer']['id'] ?? ''); $payment_method = $payment_source_key; - + $vault_id = (isset($payment_source['attributes']['vault']['id']) ? $payment_source['attributes']['vault']['id'] : ''); + $vault_customer_id = (isset($payment_source['attributes']['vault']['customer']['id']) ? $payment_source['attributes']['vault']['customer']['id'] : ''); + $card_last_digits = (isset($payment_source['last_digits']) ? $payment_source['last_digits'] : ''); + $card_expiry = (isset($payment_source['expiry']) ? $payment_source['expiry'] : ''); + break; } @@ -2525,115 +2969,95 @@ public function completeOrder(): void { if ($authorization_status == 'CAPTURED') { $this->error['warning'] = sprintf($this->language->get('error_authorization_captured'), $this->url->link('information/contact', '', true)); } - + if ($authorization_status == 'DENIED') { $order_status_id = $setting['order_status']['denied']['id']; $transaction_status = 'denied'; - + $this->error['warning'] = $this->language->get('error_authorization_denied'); } - + if ($authorization_status == 'EXPIRED') { $this->error['warning'] = sprintf($this->language->get('error_authorization_expired'), $this->url->link('information/contact', '', true)); } - + if ($authorization_status == 'PENDING') { $order_status_id = $setting['order_status']['pending']['id']; $transaction_status = 'pending'; } - + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); - - $this->model_checkout_order->addHistory($this->session->data['order_id'], $order_status_id, $message); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); } - + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { + if ($payment_method == 'paypal') { + $paypal_customer_token = array(); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), $payment_method); + } + + if (!empty($paypal_customer_token['vault_id'])) { + $vault_id = $paypal_customer_token['vault_id']; + $vault_customer_id = $paypal_customer_token['vault_customer_id']; + } + } + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); - - $paypal_order_data = [ - 'order_id' => $this->session->data['order_id'], - 'transaction_id' => $authorization_id, + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $authorization_id, 'transaction_status' => $transaction_status, - 'payment_method' => $payment_method, - 'vault_id' => $vault_id, - 'vault_customer_id' => $vault_customer_id, - 'environment' => $environment - ]; + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_data['total'], + 'currency_code' => $order_data['currency_code'], + 'environment' => $environment + ); $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); - } - - if (($authorization_status == 'CREATED') || ($authorization_status == 'PENDING')) { - $this->load->model('checkout/subscription'); - - $subscription_products = $this->cart->getSubscriptions(); - - $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - - $order_products = $this->model_checkout_order->getProducts($this->session->data['order_id']); - - if (isset($this->request->server['HTTP_X_REAL_IP'])) { - $ip = $this->request->server['HTTP_X_REAL_IP']; - } elseif (oc_get_ip()) { - $ip = oc_get_ip(); - } else { - $ip = ''; - } - - if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { - $forwarded_ip = $this->request->server['HTTP_X_FORWARDED_FOR']; - } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { - $forwarded_ip = $this->request->server['HTTP_CLIENT_IP']; - } else { - $forwarded_ip = ''; - } - - if (isset($this->request->server['HTTP_USER_AGENT'])) { - $user_agent = $this->request->server['HTTP_USER_AGENT']; - } else { - $user_agent = ''; - } - - if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { - $accept_language = $this->request->server['HTTP_ACCEPT_LANGUAGE']; - } else { - $accept_language = ''; - } - - foreach ($subscription_products as $item) { - foreach ($order_products as $order_product) { - $subscription_info = $this->model_checkout_subscription->getSubscriptionByOrderProductId($this->session->data['order_id'], $order_product['order_product_id']); - - if ($subscription_info && $order_product['product_id'] == $item['product_id'] && $item['product_id'] == $subscription_info['product_id']) { - $item['subscription']['subscription_id'] = $subscription_info['subscription_id']; - $item['subscription']['order_product_id'] = $order_product['order_product_id']; - $item['subscription']['name'] = $item['name']; - $item['subscription']['product_id'] = $item['product_id']; - $item['subscription']['tax'] = $this->tax->getTax($item['price'], $item['tax_class_id']); - $item['subscription']['quantity'] = $item['quantity']; - $item['subscription']['store_id'] = (int)$this->config->get('config_store_id'); - $item['subscription']['customer_id'] = $this->customer->getId(); - $item['subscription']['payment_address_id'] = $subscription_info['payment_address_id']; - $item['subscription']['payment_method'] = $subscription_info['payment_method']; - $item['subscription']['shipping_address_id'] = $subscription_info['shipping_address_id']; - $item['subscription']['shipping_method'] = $subscription_info['shipping_method']; - $item['subscription']['comment'] = $subscription_info['comment']; - $item['subscription']['affiliate_id'] = $subscription_info['affiliate_id']; - $item['subscription']['marketing_id'] = $subscription_info['marketing_id']; - $item['subscription']['tracking'] = $subscription_info['tracking']; - $item['subscription']['language_id'] = $this->config->get('config_language_id'); - $item['subscription']['currency_id'] = $subscription_info['currency_id']; - $item['subscription']['ip'] = $ip; - $item['subscription']['forwarded_ip'] = $forwarded_ip; - $item['subscription']['user_agent'] = $user_agent; - $item['subscription']['accept_language'] = $accept_language; - - $this->model_extension_payment_paypal->subscriptionPayment($item, $order_info, $paypal_order_data); - } + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); } } + + if (($authorization_status == 'CREATED') || ($authorization_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_data, $paypal_order_data); + } + } if (($authorization_status == 'CREATED') || ($authorization_status == 'PARTIALLY_CAPTURED') || ($authorization_status == 'PARTIALLY_CREATED') || ($authorization_status == 'VOIDED') || ($authorization_status == 'PENDING')) { $this->response->redirect($this->url->link('checkout/success', '', true)); @@ -2641,7 +3065,7 @@ public function completeOrder(): void { } } else { $this->model_extension_payment_paypal->log($result, 'Capture Order'); - + if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { $capture_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; $capture_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; @@ -2651,135 +3075,119 @@ public function completeOrder(): void { $payment_method = ''; $vault_id = ''; $vault_customer_id = ''; - $paypal_order_data = []; - + $card_type = ''; + $card_nice_type = ''; + $card_last_digits = ''; + $card_expiry = ''; + if (!$this->cart->hasShipping()) { $seller_protection_status = 'NOT_ELIGIBLE'; } - + foreach ($result['payment_source'] as $payment_source_key => $payment_source) { - $vault_id = ($payment_source['attributes']['vault']['id'] ?? ''); - $vault_customer_id = ($payment_source['attributes']['vault']['customer']['id'] ?? ''); $payment_method = $payment_source_key; - + $vault_id = (isset($payment_source['attributes']['vault']['id']) ? $payment_source['attributes']['vault']['id'] : ''); + $vault_customer_id = (isset($payment_source['attributes']['vault']['customer']['id']) ? $payment_source['attributes']['vault']['customer']['id'] : ''); + $card_last_digits = (isset($payment_source['last_digits']) ? $payment_source['last_digits'] : ''); + $card_expiry = (isset($payment_source['expiry']) ? $payment_source['expiry'] : ''); + break; } - + if ($capture_status == 'COMPLETED') { $order_status_id = $setting['order_status']['completed']['id']; $transaction_status = 'completed'; } - + if ($capture_status == 'DECLINED') { $order_status_id = $setting['order_status']['denied']['id']; $transaction_status = 'denied'; - + $this->error['warning'] = $this->language->get('error_capture_declined'); } - + if ($capture_status == 'FAILED') { $this->error['warning'] = sprintf($this->language->get('error_capture_failed'), $this->url->link('information/contact', '', true)); } - + if ($capture_status == 'PENDING') { $order_status_id = $setting['order_status']['pending']['id']; $transaction_status = 'pending'; } - + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); - - $this->model_checkout_order->addHistory($this->session->data['order_id'], $order_status_id, $message); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); } - + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { + if ($payment_method == 'paypal') { + $paypal_customer_token = array(); + + if ($setting['general']['vault_status'] && $this->customer->isLogged()) { + $paypal_customer_token = $this->model_extension_payment_paypal->getPayPalCustomerMainToken($this->customer->getId(), $payment_method); + } + + if (!empty($paypal_customer_token['vault_id'])) { + $vault_id = $paypal_customer_token['vault_id']; + $vault_customer_id = $paypal_customer_token['vault_customer_id']; + } + } + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); - - $paypal_order_data = [ - 'order_id' => $this->session->data['order_id'], - 'transaction_id' => $capture_id, + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $capture_id, 'transaction_status' => $transaction_status, - 'payment_method' => $payment_method, - 'vault_id' => $vault_id, - 'vault_customer_id' => $vault_customer_id, - 'environment' => $environment - ]; + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_data['total'], + 'currency_code' => $order_data['currency_code'], + 'environment' => $environment + ); $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); - } - - if (($capture_status == 'COMPLETED') || ($capture_status == 'PENDING')) { - $this->load->model('checkout/subscription'); - - // Loop through any products that are subscription items - $subscription_products = $this->cart->getSubscriptions(); - - $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - - $order_products = $this->model_checkout_order->getProducts($this->session->data['order_id']); - - if (isset($this->request->server['HTTP_X_REAL_IP'])) { - $ip = $this->request->server['HTTP_X_REAL_IP']; - } elseif (oc_get_ip()) { - $ip = oc_get_ip(); - } else { - $ip = ''; - } - - if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { - $forwarded_ip = $this->request->server['HTTP_X_FORWARDED_FOR']; - } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { - $forwarded_ip = $this->request->server['HTTP_CLIENT_IP']; - } else { - $forwarded_ip = ''; - } - - if (isset($this->request->server['HTTP_USER_AGENT'])) { - $user_agent = $this->request->server['HTTP_USER_AGENT']; - } else { - $user_agent = ''; - } - - if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { - $accept_language = $this->request->server['HTTP_ACCEPT_LANGUAGE']; - } else { - $accept_language = ''; - } - - foreach ($subscription_products as $item) { - foreach ($order_products as $order_product) { - $subscription_info = $this->model_checkout_subscription->getSubscriptionByOrderProductId($this->session->data['order_id'], $order_product['order_product_id']); - - if ($subscription_info && $order_product['product_id'] == $item['product_id'] && $item['product_id'] == $subscription_info['product_id']) { - $item['subscription']['subscription_id'] = $subscription_info['subscription_id']; - $item['subscription']['order_product_id'] = $order_product['order_product_id']; - $item['subscription']['name'] = $item['name']; - $item['subscription']['product_id'] = $item['product_id']; - $item['subscription']['tax'] = $this->tax->getTax($item['price'], $item['tax_class_id']); - $item['subscription']['quantity'] = $item['quantity']; - $item['subscription']['store_id'] = (int)$this->config->get('config_store_id'); - $item['subscription']['customer_id'] = $this->customer->getId(); - $item['subscription']['payment_address_id'] = $subscription_info['payment_address_id']; - $item['subscription']['payment_method'] = $subscription_info['payment_method']; - $item['subscription']['shipping_address_id'] = $subscription_info['shipping_address_id']; - $item['subscription']['shipping_method'] = $subscription_info['shipping_method']; - $item['subscription']['comment'] = $subscription_info['comment']; - $item['subscription']['affiliate_id'] = $subscription_info['affiliate_id']; - $item['subscription']['marketing_id'] = $subscription_info['marketing_id']; - $item['subscription']['tracking'] = $subscription_info['tracking']; - $item['subscription']['language_id'] = $this->config->get('config_language_id'); - $item['subscription']['currency_id'] = $subscription_info['currency_id']; - $item['subscription']['ip'] = $ip; - $item['subscription']['forwarded_ip'] = $forwarded_ip; - $item['subscription']['user_agent'] = $user_agent; - $item['subscription']['accept_language'] = $accept_language; - - $this->model_extension_payment_paypal->subscriptionPayment($item, $order_info, $paypal_order_data); - } + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); } } - + + if (($capture_status == 'COMPLETED') || ($capture_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_data, $paypal_order_data); + } + } + if (($capture_status == 'COMPLETED') || ($capture_status == 'PARTIALLY_REFUNDED') || ($capture_status == 'REFUNDED') || ($capture_status == 'PENDING')) { $this->response->redirect($this->url->link('checkout/success', '', true)); } @@ -2787,86 +3195,64 @@ public function completeOrder(): void { } } } - + unset($this->session->data['paypal_order_id']); - - if ($this->error) { + + if ($this->error) { $this->session->data['error'] = $this->error['warning']; - + $this->response->redirect($this->url->link('checkout/checkout', '', true)); } - } - + } + $this->response->redirect($this->url->link('checkout/cart', '', true)); } - - /** - * Payment Address - * - * @return void - */ - public function paymentAddress(): void { + + public function paymentAddress() { $this->load->language('extension/payment/paypal'); - - $data['guest'] = $this->session->data['guest'] ?? []; - $data['payment_address'] = $this->session->data['payment_address'] ?? []; - + + $data['guest'] = isset($this->session->data['guest']) ? $this->session->data['guest'] : array(); + $data['payment_address'] = isset($this->session->data['payment_address']) ? $this->session->data['payment_address'] : array(); + $this->load->model('localisation/country'); $data['countries'] = $this->model_localisation_country->getCountries(); - + $this->load->model('account/custom_field'); $data['custom_fields'] = $this->model_account_custom_field->getCustomFields(); - + $this->response->setOutput($this->load->view('extension/payment/paypal/payment_address', $data)); } - - /** - * Shipping Address - * - * @return void - */ - public function shippingAddress(): void { + + public function shippingAddress() { $this->load->language('extension/payment/paypal'); - - $data['shipping_address'] = $this->session->data['shipping_address'] ?? []; - + + $data['shipping_address'] = isset($this->session->data['shipping_address']) ? $this->session->data['shipping_address'] : array(); + $this->load->model('localisation/country'); $data['countries'] = $this->model_localisation_country->getCountries(); - + $this->load->model('account/custom_field'); $data['custom_fields'] = $this->model_account_custom_field->getCustomFields(); - + $this->response->setOutput($this->load->view('extension/payment/paypal/shipping_address', $data)); } - - /** - * Confirm Shipping - * - * @return void - */ - public function confirmShipping(): void { + + public function confirmShipping() { $this->validateShipping($this->request->post['shipping_method']); $this->response->redirect($this->url->link('extension/payment/paypal/confirmOrder', '', true)); } - - /** - * Confirm Payment Address - * - * @return void - */ - public function confirmPaymentAddress(): void { + + public function confirmPaymentAddress() { $this->load->language('extension/payment/paypal'); - - $json = []; - - $json['url'] = ''; - - if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validatePaymentAddress()) { + + $data['url'] = ''; + + if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validatePaymentAddress()) { $this->session->data['guest']['firstname'] = $this->request->post['firstname']; $this->session->data['guest']['lastname'] = $this->request->post['lastname']; $this->session->data['guest']['email'] = $this->request->post['email']; @@ -2875,7 +3261,7 @@ public function confirmPaymentAddress(): void { if (isset($this->request->post['custom_field']['account'])) { $this->session->data['guest']['custom_field'] = $this->request->post['custom_field']['account']; } else { - $this->session->data['guest']['custom_field'] = []; + $this->session->data['guest']['custom_field'] = array(); } $this->session->data['payment_address']['firstname'] = $this->request->post['firstname']; @@ -2885,8 +3271,8 @@ public function confirmPaymentAddress(): void { $this->session->data['payment_address']['address_2'] = $this->request->post['address_2']; $this->session->data['payment_address']['postcode'] = $this->request->post['postcode']; $this->session->data['payment_address']['city'] = $this->request->post['city']; - $this->session->data['payment_address']['country_id'] = (int)$this->request->post['country_id']; - $this->session->data['payment_address']['zone_id'] = (int)$this->request->post['zone_id']; + $this->session->data['payment_address']['country_id'] = $this->request->post['country_id']; + $this->session->data['payment_address']['zone_id'] = $this->request->post['zone_id']; $this->load->model('localisation/country'); @@ -2907,7 +3293,7 @@ public function confirmPaymentAddress(): void { if (isset($this->request->post['custom_field']['address'])) { $this->session->data['payment_address']['custom_field'] = $this->request->post['custom_field']['address']; } else { - $this->session->data['payment_address']['custom_field'] = []; + $this->session->data['payment_address']['custom_field'] = array(); } $this->load->model('localisation/zone'); @@ -2921,27 +3307,20 @@ public function confirmPaymentAddress(): void { $this->session->data['payment_address']['zone'] = ''; $this->session->data['payment_address']['zone_code'] = ''; } - - $json['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); + + $data['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); } - $json['error'] = $this->error; - + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Confirm Shipping Address - * - * @return void - */ - public function confirmShippingAddress(): void { + + public function confirmShippingAddress() { $this->load->language('extension/payment/paypal'); - - $json = []; - - if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateShippingAddress()) { + + if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateShippingAddress()) { $this->session->data['shipping_address']['firstname'] = $this->request->post['firstname']; $this->session->data['shipping_address']['lastname'] = $this->request->post['lastname']; $this->session->data['shipping_address']['company'] = $this->request->post['company']; @@ -2949,8 +3328,8 @@ public function confirmShippingAddress(): void { $this->session->data['shipping_address']['address_2'] = $this->request->post['address_2']; $this->session->data['shipping_address']['postcode'] = $this->request->post['postcode']; $this->session->data['shipping_address']['city'] = $this->request->post['city']; - $this->session->data['shipping_address']['country_id'] = (int)$this->request->post['country_id']; - $this->session->data['shipping_address']['zone_id'] = (int)$this->request->post['zone_id']; + $this->session->data['shipping_address']['country_id'] = $this->request->post['country_id']; + $this->session->data['shipping_address']['zone_id'] = $this->request->post['zone_id']; $this->load->model('localisation/country'); @@ -2983,80 +3362,617 @@ public function confirmShippingAddress(): void { if (isset($this->request->post['custom_field'])) { $this->session->data['shipping_address']['custom_field'] = $this->request->post['custom_field']['address']; } else { - $this->session->data['shipping_address']['custom_field'] = []; + $this->session->data['shipping_address']['custom_field'] = array(); } - - $json['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); + + $data['url'] = $this->url->link('extension/payment/paypal/confirmOrder', '', true); } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function deleteCustomerToken() { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); - $json['error'] = $this->error; + if ($this->customer->isLogged() && isset($this->request->post['index'])) { + $card_token_index = $this->request->post['index']; + + $card_customer_tokens = $this->model_extension_payment_paypal->getPayPalCustomerTokens($this->customer->getId(), 'card'); + + if (!empty($card_customer_tokens[$card_token_index]['vault_id'])) { + $vault_id = $card_customer_tokens[$card_token_index]['vault_id']; + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $merchant_id = $this->config->get('payment_paypal_merchant_id'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $result = $paypal->setAccessToken($token_info); + + $result = $paypal->deletePaymentToken($vault_id); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + } + + + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + } + + if ($result && !$this->error) { + $this->model_extension_payment_paypal->deletePayPalCustomerToken($this->customer->getId(), 'card', $vault_id); + + $data['success'] = true; + } + } + } + + $data['error'] = $this->error; + $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); + $this->response->setOutput(json_encode($data)); } - - /** - * Webhook - * - * @return bool - */ - public function webhook(): bool { - if (!empty($this->request->get['webhook_token'])) { - $_config = new \Config(); + + public function addOrderHistory() { + if (!empty($this->request->get['order_history_token']) && !empty($this->request->post['order_id']) && !empty($this->request->post['order_status_id'])) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + if (hash_equals($setting['general']['order_history_token'], $this->request->get['order_history_token'])) { + $this->load->model('checkout/order'); + $this->model_checkout_order->addOrderHistory($this->request->post['order_id'], $this->request->post['order_status_id'], '', true); + + $data['success'] = $this->language->get('success_order'); + } + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function callback() { + if (!empty($this->request->get['callback_token'])) { + $this->load->language('extension/payment/paypal'); + + $this->load->model('extension/payment/paypal'); + + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + + if (hash_equals($setting['general']['callback_token'], $this->request->get['callback_token']) && !empty($this->session->data['order_id']) && !empty($this->session->data['paypal_order_id']) && isset($this->session->data['paypal_card_token_index'])) { + $order_id = $this->session->data['order_id']; + $paypal_order_id = $this->session->data['paypal_order_id']; + $card_token_index = $this->session->data['paypal_card_token_index']; + + $card_customer_tokens = $this->model_extension_payment_paypal->getPayPalCustomerTokens($this->customer->getId(), 'card'); + + if (!empty($card_customer_tokens[$card_token_index]['vault_id'])) { + $vault_id = $card_customer_tokens[$card_token_index]['vault_id']; + $vault_customer_id = $card_customer_tokens[$card_token_index]['vault_customer_id']; + $card_type = $card_customer_tokens[$card_token_index]['card_type']; + $card_nice_type = $card_customer_tokens[$card_token_index]['card_nice_type']; + $card_last_digits = $card_customer_tokens[$card_token_index]['card_last_digits']; + $card_expiry = $card_customer_tokens[$card_token_index]['card_expiry']; + + $client_id = $this->config->get('payment_paypal_client_id'); + $secret = $this->config->get('payment_paypal_secret'); + $environment = $this->config->get('payment_paypal_environment'); + $partner_id = $setting['partner'][$environment]['partner_id']; + $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $vault_status = $setting['general']['vault_status']; + $transaction_method = $setting['general']['transaction_method']; + + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, + 'partner_attribution_id' => $partner_attribution_id + ); + + $paypal = new PayPal($paypal_info); + + $token_info = array( + 'grant_type' => 'client_credentials' + ); + + $paypal->setAccessToken($token_info); + + $paypal_order_info = $paypal->getOrder($paypal_order_id); + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (isset($paypal_order_info['payment_source']['card']) && !$this->error) { + $this->model_extension_payment_paypal->log($paypal_order_info['payment_source']['card'], 'Card'); + + $liability_shift = (isset($paypal_order_info['payment_source']['card']['authentication_result']['liability_shift']) ? $paypal_order_info['payment_source']['card']['authentication_result']['liability_shift'] : ''); + $enrollment_status = (isset($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['enrollment_status']) ? $paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['enrollment_status'] : ''); + $authentication_status = (isset($paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['authentication_status']) ? $paypal_order_info['payment_source']['card']['authentication_result']['three_d_secure']['authentication_status'] : ''); + + if ($enrollment_status == 'Y') { + if (($authentication_status == 'N') && !$setting['card']['secure_scenario']['failed_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['failed_authentication']['error']); + } + + if (($authentication_status == 'R') && !$setting['card']['secure_scenario']['rejected_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['rejected_authentication']['error']); + } + + if (($authentication_status == 'A') && !$setting['card']['secure_scenario']['attempted_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['attempted_authentication']['error']); + } + + if (($authentication_status == 'U') && !$setting['card']['secure_scenario']['unable_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['unable_authentication']['error']); + } + + if (($authentication_status == 'C') && !$setting['card']['secure_scenario']['challenge_authentication']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['challenge_authentication']['error']); + } + } + + if (($enrollment_status == 'N') && !$setting['card']['secure_scenario']['card_ineligible']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['card_ineligible']['error']); + } + + if (($enrollment_status == 'U') && !$setting['card']['secure_scenario']['system_unavailable']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_unavailable']['error']); + } + + if (($enrollment_status == 'B') && !$setting['card']['secure_scenario']['system_bypassed']) { + $this->error['warning'] = $this->language->get($setting['card_secure_scenario']['system_bypassed']['error']); + } + } + + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + } + + if (!$this->error) { + if ($transaction_method == 'authorize') { + $result = $paypal->setOrderAuthorize($paypal_order_id); + } else { + $result = $paypal->setOrderCapture($paypal_order_id); + } + + if ($paypal->hasErrors()) { + $error_messages = array(); + + $errors = $paypal->getErrors(); + + foreach ($errors as $error) { + if (isset($error['details'][0]['issue']) && ($error['details'][0]['issue'] == 'INSTRUMENT_DECLINED')) { + $data['restart'] = true; + } + + if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { + $error['message'] = $this->language->get('error_timeout'); + } + + if (isset($error['details'][0]['description'])) { + $error_messages[] = $error['details'][0]['description']; + } elseif (isset($error['message'])) { + $error_messages[] = $error['message']; + } + + $this->model_extension_payment_paypal->log($error, $error['message']); + } + + $this->error['warning'] = implode(' ', $error_messages); + } + + if (!empty($this->error['warning'])) { + $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); + } + + if (!$this->error) { + $this->load->model('checkout/order'); + + $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); + + if ($transaction_method == 'authorize') { + $this->model_extension_payment_paypal->log($result, 'Authorize Order'); + + if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { + $authorization_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; + $authorization_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; + $seller_protection_status = $result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status']; + $order_status_id = 0; + $transaction_status = ''; + $payment_method = 'card'; + + if (!$this->cart->hasShipping()) { + $seller_protection_status = 'NOT_ELIGIBLE'; + } + + if ($authorization_status == 'CREATED') { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'created'; + } + if ($authorization_status == 'CAPTURED') { + $this->error['warning'] = sprintf($this->language->get('error_authorization_captured'), $this->url->link('information/contact', '', true)); + } + + if ($authorization_status == 'DENIED') { + $order_status_id = $setting['order_status']['denied']['id']; + $transaction_status = 'denied'; + + $this->error['warning'] = $this->language->get('error_authorization_denied'); + } + + if ($authorization_status == 'EXPIRED') { + $this->error['warning'] = sprintf($this->language->get('error_authorization_expired'), $this->url->link('information/contact', '', true)); + } + + if ($authorization_status == 'PENDING') { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'pending'; + } + + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { + $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); + } + + if (($authorization_status == 'CREATED') || ($authorization_status == 'DENIED') || ($authorization_status == 'PENDING')) { + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $authorization_id, + 'transaction_status' => $transaction_status, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_info['total'], + 'currency_code' => $order_info['currency_code'], + 'environment' => $environment + ); + + $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); + } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); + } + } + + if (($authorization_status == 'CREATED') || ($authorization_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_info, $paypal_order_data); + } + } + + if (($authorization_status == 'CREATED') || ($authorization_status == 'PARTIALLY_CAPTURED') || ($authorization_status == 'PARTIALLY_CREATED') || ($authorization_status == 'VOIDED') || ($authorization_status == 'PENDING')) { + $this->response->redirect($this->url->link('checkout/success', '', true)); + } + } + } else { + $this->model_extension_payment_paypal->log($result, 'Capture Order'); + + if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { + $capture_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; + $capture_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; + $seller_protection_status = $result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status']; + + $order_status_id = 0; + $transaction_status = ''; + $payment_method = 'card'; + + if (!$this->cart->hasShipping()) { + $seller_protection_status = 'NOT_ELIGIBLE'; + } + + if ($capture_status == 'COMPLETED') { + $order_status_id = $setting['order_status']['completed']['id']; + $transaction_status = 'completed'; + } + + if ($capture_status == 'DECLINED') { + $order_status_id = $setting['order_status']['denied']['id']; + $transaction_status = 'denied'; + + $this->error['warning'] = $this->language->get('error_capture_declined'); + } + + if ($capture_status == 'FAILED') { + $this->error['warning'] = sprintf($this->language->get('error_capture_failed'), $this->url->link('information/contact', '', true)); + } + + if ($capture_status == 'PENDING') { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'pending'; + } + + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { + $message = sprintf($this->language->get('text_order_message'), $seller_protection_status); + + $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $order_status_id, $message); + } + + if (($capture_status == 'COMPLETED') || ($capture_status == 'DECLINED') || ($capture_status == 'PENDING')) { + $this->model_extension_payment_paypal->deletePayPalOrder($this->session->data['order_id']); + + $paypal_order_data = array( + 'order_id' => $this->session->data['order_id'], + 'paypal_order_id' => $paypal_order_id, + 'transaction_id' => $capture_id, + 'transaction_status' => $transaction_status, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry, + 'total' => $order_info['total'], + 'currency_code' => $order_info['currency_code'], + 'environment' => $environment + ); + + $this->model_extension_payment_paypal->addPayPalOrder($paypal_order_data); + + if ($vault_id && $this->customer->isLogged()) { + $customer_id = $this->customer->getId(); + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); + } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); + } + } + + if (($capture_status == 'COMPLETED') || ($capture_status == 'PENDING')) { + $recurring_products = $this->cart->getRecurringProducts(); + + foreach ($recurring_products as $recurring_product) { + $this->model_extension_payment_paypal->recurringPayment($recurring_product, $order_info, $paypal_order_data); + } + } + + if (($capture_status == 'COMPLETED') || ($capture_status == 'PARTIALLY_REFUNDED') || ($capture_status == 'REFUNDED') || ($capture_status == 'PENDING')) { + $this->response->redirect($this->url->link('checkout/success', '', true)); + } + } + } + } + } + } + + $this->document->setTitle($this->language->get('text_failure_page_title')); + + $data['breadcrumbs'] = array(); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_home'), + 'href' => $this->url->link('common/home', '', true) + ); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_cart'), + 'href' => $this->url->link('checkout/cart', '', true) + ); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_paypal'), + 'href' => $this->url->link('extension/payment/paypal/callback', '', true) + ); + + $data['text_title'] = $this->language->get('text_failure_page_title'); + $data['text_message'] = sprintf($this->language->get('text_failure_page_message'), $this->url->link('information/contact', '', true)); + + if (!empty($this->error['warning'])) { + $data['text_message'] = $this->error['warning']; + } + + $data['continue'] = $this->url->link('common/home'); + + $data['column_left'] = $this->load->controller('common/column_left'); + $data['column_right'] = $this->load->controller('common/column_right'); + $data['content_top'] = $this->load->controller('common/content_top'); + $data['content_bottom'] = $this->load->controller('common/content_bottom'); + $data['footer'] = $this->load->controller('common/footer'); + $data['header'] = $this->load->controller('common/header'); + + $this->response->setOutput($this->load->view('extension/payment/paypal/failure', $data)); + + return true; + } + } + + return false; + } + + public function webhook() { + if (!empty($this->request->get['webhook_token'])) { + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); + $webhook_info = json_decode(html_entity_decode(file_get_contents('php://input')), true); - - if (hash_equals($setting['general']['webhook_token'], $this->request->get['webhook_token']) && !empty($webhook_info['id']) && !empty($webhook_info['event_type'])) { + + if (hash_equals($setting['general']['webhook_token'], $this->request->get['webhook_token']) && !empty($webhook_info['id']) && !empty($webhook_info['event_type'])) { $this->load->model('extension/payment/paypal'); - + $this->load->model('checkout/order'); + $this->model_extension_payment_paypal->log($webhook_info, 'Webhook'); - + $webhook_event_id = $webhook_info['id']; - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; + $vault_status = $setting['general']['vault_status']; $transaction_method = $setting['general']['transaction_method']; - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $webhook_repeat = 1; - + while ($webhook_repeat) { $webhook_event = $paypal->getWebhookEvent($webhook_event_id); - $errors = []; - + $errors = array(); + $webhook_repeat = 0; - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $webhook_repeat = 1; @@ -3064,166 +3980,237 @@ public function webhook(): bool { } } } - - if (isset($webhook_event['resource']['invoice_id']) && (str_contains($webhook_event['resource']['invoice_id'], '_')) && !$errors) { + + if (!empty($webhook_event['resource']['invoice_id']) && (strpos($webhook_event['resource']['invoice_id'], '_') !== false) && !$errors) { $invoice_id = explode('_', $webhook_event['resource']['invoice_id']); $order_id = reset($invoice_id); + + $order_info = $this->model_checkout_order->getOrder($order_id); + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrder($order_id); + + if ($order_info && $paypal_order_info) { + $order_status_id = 0; + $transaction_id = $paypal_order_info['transaction_id']; + $transaction_status = $paypal_order_info['transaction_status']; + + if ($webhook_event['event_type'] == 'PAYMENT.AUTHORIZATION.CREATED') { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'created'; + } + + if ($webhook_event['event_type'] == 'PAYMENT.AUTHORIZATION.VOIDED') { + $order_status_id = $setting['order_status']['voided']['id']; + $transaction_status = 'voided'; + } + + if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.COMPLETED') { + if (!empty($webhook_event['resource']['final_capture'])) { + $order_status_id = $setting['order_status']['completed']['id']; + $transaction_status = 'completed'; + } else { + $order_status_id = $setting['order_status']['partially_captured']['id']; + $transaction_status = 'partially_captured'; + } + } + + if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.DENIED') { + $order_status_id = $setting['order_status']['denied']['id']; + $transaction_status = 'denied'; + } + + if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.PENDING') { + $order_status_id = $setting['order_status']['pending']['id']; + $transaction_status = 'pending'; + } + + if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.REFUNDED') { + $result = $paypal->getPaymentCapture($transaction_id); + + if (!empty($result['status'] == 'REFUNDED')) { + $order_status_id = $setting['order_status']['refunded']['id']; + $transaction_status = 'refunded'; + } elseif (!empty($result['status'] == 'PARTIALLY_REFUNDED')) { + $order_status_id = $setting['order_status']['partially_refunded']['id']; + $transaction_status = 'partially_refunded'; + } + } + + if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.REVERSED') { + $order_status_id = $setting['order_status']['reversed']['id']; + $transaction_status = 'reversed'; + } + + if ($webhook_event['event_type'] == 'CHECKOUT.ORDER.COMPLETED') { + $order_status_id = $setting['order_status']['completed']['id']; + } + + if ($order_status_id && ($order_info['order_status_id'] != $order_status_id)) { + $this->load->model('checkout/order'); - $order_status_id = 0; - $transaction_status = ''; - - if ($webhook_event['event_type'] == 'PAYMENT.AUTHORIZATION.CREATED') { - $order_status_id = $setting['order_status']['pending']['id']; - $transaction_status = 'created'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.AUTHORIZATION.VOIDED') { - $order_status_id = $setting['order_status']['voided']['id']; - $transaction_status = 'voided'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.COMPLETED') { - $order_status_id = $setting['order_status']['completed']['id']; - $transaction_status = 'completed'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.DENIED') { - $order_status_id = $setting['order_status']['denied']['id']; - $transaction_status = 'denied'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.PENDING') { - $order_status_id = $setting['order_status']['pending']['id']; - $transaction_status = 'pending'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.REFUNDED') { - $order_status_id = $setting['order_status']['refunded']['id']; - $transaction_status = 'refunded'; - } - - if ($webhook_event['event_type'] == 'PAYMENT.CAPTURE.REVERSED') { - $order_status_id = $setting['order_status']['reversed']['id']; - $transaction_status = 'reversed'; - } - - if ($webhook_event['event_type'] == 'CHECKOUT.ORDER.COMPLETED') { - $order_status_id = $setting['order_status']['completed']['id']; - } - - if ($order_status_id) { - $this->load->model('checkout/order'); - - $this->model_checkout_order->addHistory($order_id, $order_status_id, '', true); - } - - if (isset($webhook_event['resource']['id']) && $transaction_status) { - $transaction_id = $webhook_event['resource']['id']; - - $paypal_order_data = [ - 'order_id' => $order_id, - 'transaction_status' => $transaction_status - ]; - - if (($transaction_status != 'refunded') && ($transaction_status != 'reversed')) { - $paypal_order_data['transaction_id'] = $transaction_id; + $this->model_checkout_order->addOrderHistory($order_id, $order_status_id, '', true); } + + if (isset($webhook_event['resource']['id']) && $transaction_status) { + $transaction_id = $webhook_event['resource']['id']; + + $paypal_order_data = array(); + + $paypal_order_data['order_id'] = $order_id; + $paypal_order_data['transaction_status'] = $transaction_status; + + if (($transaction_status == 'created') && ($transaction_status == 'completed')) { + $paypal_order_data['transaction_id'] = $transaction_id; + } + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + } + } + } + + if (($webhook_event['event_type'] == 'VAULT.PAYMENT-TOKEN.CREATED') && !empty($webhook_info['resource']['id']) && !empty($webhook_info['resource']['customer']['id']) && !empty($webhook_event['resource']['metadata']['order_id']) && !$errors) { + $paypal_order_id = $webhook_event['resource']['metadata']['order_id']; + + $paypal_order_info = $this->model_extension_payment_paypal->getPayPalOrderByPayPalOrderId($paypal_order_id); + + if ($paypal_order_info) { + $order_id = $paypal_order_info['order_id']; + $payment_method = $paypal_order_info['payment_method']; + $vault_id = $webhook_event['resource']['id']; + $vault_customer_id = $webhook_event['resource']['customer']['id']; + $card_type = $paypal_order_info['card_type']; + $card_nice_type = $paypal_order_info['card_nice_type']; + $card_last_digits = (isset($webhook_event['resource']['payment_source']['card']['last_digits']) ? $webhook_event['resource']['payment_source']['card']['last_digits'] : ''); + $card_expiry = (isset($webhook_event['resource']['payment_source']['card']['expiry']) ? $webhook_event['resource']['payment_source']['card']['expiry'] : ''); + + $paypal_order_data = array( + 'order_id' => $order_id, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + $this->model_extension_payment_paypal->editPayPalOrder($paypal_order_data); + + $order_info = $this->model_checkout_order->getOrder($order_id); + + if ($vault_id && !empty($order_info['customer_id'])) { + $customer_id = $order_info['customer_id']; + + $paypal_customer_token_info = $this->model_extension_payment_paypal->getPayPalCustomerToken($customer_id, $payment_method, $vault_id); + + if (!$paypal_customer_token_info) { + $paypal_customer_token_data = array( + 'customer_id' => $customer_id, + 'payment_method' => $payment_method, + 'vault_id' => $vault_id, + 'vault_customer_id' => $vault_customer_id, + 'card_type' => $card_type, + 'card_nice_type' => $card_nice_type, + 'card_last_digits' => $card_last_digits, + 'card_expiry' => $card_expiry + ); + + $this->model_extension_payment_paypal->addPayPalCustomerToken($paypal_customer_token_data); + } + + $this->model_extension_payment_paypal->setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id); + } } } header('HTTP/1.1 200 OK'); - + return true; } } - + return false; } - - /** - * Cron - * - * @return bool - */ - public function cron(): bool { + + public function cron() { if (!empty($this->request->get['cron_token'])) { - $_config = new \Config(); + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + if (hash_equals($setting['general']['cron_token'], $this->request->get['cron_token'])) { $this->load->model('extension/payment/paypal'); - + $this->model_extension_payment_paypal->cronPayment(); - + return true; } } - + return false; } - - /** - * Header Before - * - * @param string $route - * @param array $data - * - * @return void - */ - public function header_before(string &$route, array &$data): void { + + public function update() { $this->load->model('extension/payment/paypal'); - + + $this->model_extension_payment_paypal->update(); + } + + public function header_before($route, &$data) { + $this->load->model('extension/payment/paypal'); + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { - $_config = new \Config(); + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + if (isset($this->request->get['route'])) { $route = $this->request->get['route']; } else { $route = 'common/home'; - } - - $params = []; - + } + + $params = array(); + if (($route == 'common/home') && $setting['message']['home']['status']) { $params['page_code'] = 'home'; } - - if (($route == 'product/product') && !empty($this->request->get['product_id']) && ($setting['button']['product']['status'] || $setting['message']['product']['status'])) { + + if (($route == 'product/product') && ($setting['button']['product']['status'] || $setting['googlepay_button']['product']['status'] || $setting['applepay_button']['product']['status'] || $setting['message']['product']['status'])) { $params['page_code'] = 'product'; - $params['product_id'] = (int)$this->request->get['product_id']; } - - if (($route == 'checkout/cart') && ($setting['button']['cart']['status'] || $setting['message']['cart']['status'])) { + + if (($route == 'checkout/cart') && ($setting['button']['cart']['status'] || $setting['googlepay_button']['cart']['status'] || $setting['applepay_button']['cart']['status'] || $setting['message']['cart']['status'])) { $params['page_code'] = 'cart'; } - - if (($route == 'checkout/checkout') && ($setting['button']['checkout']['status'] || $setting['googlepay_button']['status'] || $setting['applepay_button']['status'] || $setting['card']['status'] || $setting['message']['checkout']['status'])) { + + if (($route == $setting['general']['checkout_route']) && ($setting['button']['checkout']['status'] || $setting['googlepay_button']['checkout']['status'] || $setting['applepay_button']['checkout']['status'] || $setting['card']['status'] || $setting['message']['checkout']['status'])) { $params['page_code'] = 'checkout'; } - + if ($params) { $theme = $this->config->get('theme_' . $this->config->get('config_theme') . '_directory'); - + if (file_exists(DIR_TEMPLATE . $theme . '/stylesheet/paypal/paypal.css')) { $this->document->addStyle('catalog/view/theme/' . $theme . '/stylesheet/paypal/paypal.css'); } else { $this->document->addStyle('catalog/view/theme/default/stylesheet/paypal/paypal.css'); } - - if ($params['page_code'] == 'checkout') { + + if (!empty($setting['googlepay_button'][$params['page_code']]['status'])) { + $this->document->addScript('https://pay.google.com/gp/p/js/pay.js'); + } + + if (!empty($setting['applepay_button'][$params['page_code']]['status']) && $this->isApple()) { + $this->document->addScript('https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js'); + } + + if ($params['page_code'] == 'checkout') { if ($setting['card']['status']) { if (file_exists(DIR_TEMPLATE . $theme . '/stylesheet/paypal/card.css')) { $this->document->addStyle('catalog/view/theme/' . $theme . '/stylesheet/paypal/card.css'); @@ -3231,149 +4218,116 @@ public function header_before(string &$route, array &$data): void { $this->document->addStyle('catalog/view/theme/default/stylesheet/paypal/card.css'); } } - - if ($setting['googlepay_button']['status']) { - $this->document->addScript('https://pay.google.com/gp/p/js/pay.js'); - } - - if ($setting['applepay_button']['status']) { - $this->document->addScript('https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js'); - } } - + $this->document->addScript('catalog/view/javascript/paypal/paypal.js?' . http_build_query($params)); } - } + } } - - /** - * Extension Get Extensions After - * - * @param string $route - * @param array $data - * @param mixed $output - */ - public function extension_get_extensions_after(string &$route, array &$data, &$output): void { + + public function extension_get_extensions_after($route, $data, &$output) { if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret')) { $type = $data[0]; - - if ($type == 'payment') { - $_config = new \Config(); + + if ($type == 'payment') { + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - - if (!empty($setting['paylater_country'][$setting['general']['country_code']]) && ($setting['button']['checkout']['funding']['paylater'] != 2)) { + + $currency_code = $this->session->data['currency']; + + if (!empty($setting['paylater_country'][$setting['general']['country_code']]) && ($currency_code == $setting['general']['currency_code']) && ($setting['button']['checkout']['funding']['paylater'] != 2)) { $this->config->set('payment_paypal_paylater_status', 1); - - $output[] = [ + + $output[] = array( 'extension_id' => 0, - 'type' => 'payment', - 'code' => 'paypal_paylater' - ]; + 'type' => 'payment', + 'code' => 'paypal_paylater' + ); } - - if ($setting['googlepay_button']['status']) { + + if ($setting['googlepay_button']['checkout']['status']) { $this->config->set('payment_paypal_googlepay_status', 1); - - $output[] = [ + + $output[] = array( 'extension_id' => 0, - 'type' => 'payment', - 'code' => 'paypal_googlepay' - ]; + 'type' => 'payment', + 'code' => 'paypal_googlepay' + ); } - - if ($setting['applepay_button']['status'] && $this->isApple()) { + + if ($setting['applepay_button']['checkout']['status'] && $this->isApple()) { $this->config->set('payment_paypal_applepay_status', 1); - - $output[] = [ + + $output[] = array( 'extension_id' => 0, - 'type' => 'payment', - 'code' => 'paypal_applepay' - ]; + 'type' => 'payment', + 'code' => 'paypal_applepay' + ); } } - } + } } - - /** - * Order Delete Order Before - * - * @param string $route - * @param array $data - * - * @return void - */ - public function order_delete_order_before(string &$route, array &$data): void { + + public function order_delete_order_before($route, $data) { $this->load->model('extension/payment/paypal'); $order_id = $data[0]; - $this->model_extension_payment_paypal->deleteOrderSubscription($order_id); + $this->model_extension_payment_paypal->deleteOrderRecurring($order_id); $this->model_extension_payment_paypal->deletePayPalOrder($order_id); - $this->model_extension_payment_paypal->deletePayPalOrderSubscription($order_id); + $this->model_extension_payment_paypal->deletePayPalOrderRecurring($order_id); } - - /** - * Validate Shipping - * - * @param string $code - * - * @return bool - */ - private function validateShipping(string $code): bool { + + private function validateShipping($code) { $this->load->language('checkout/cart'); $this->load->language('extension/payment/paypal'); if (empty($code)) { $this->session->data['error_warning'] = $this->language->get('error_shipping'); - + return false; } else { $shipping = explode('.', $code); if (!isset($shipping[0]) || !isset($shipping[1]) || !isset($this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]])) { $this->session->data['error_warning'] = $this->language->get('error_shipping'); - + return false; } else { $this->session->data['shipping_method'] = $this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]]; $this->session->data['success'] = $this->language->get('text_shipping_updated'); - + return true; } } } - - /** - * Validate Payment Address - * - * @return bool - */ - private function validatePaymentAddress(): bool { - if ((oc_strlen(trim($this->request->post['firstname'])) < 1) || (oc_strlen(trim($this->request->post['firstname'])) > 32)) { + + private function validatePaymentAddress() { + if ((utf8_strlen(trim($this->request->post['firstname'])) < 1) || (utf8_strlen(trim($this->request->post['firstname'])) > 32)) { $this->error['firstname'] = $this->language->get('error_firstname'); } - if ((oc_strlen(trim($this->request->post['lastname'])) < 1) || (oc_strlen(trim($this->request->post['lastname'])) > 32)) { + if ((utf8_strlen(trim($this->request->post['lastname'])) < 1) || (utf8_strlen(trim($this->request->post['lastname'])) > 32)) { $this->error['lastname'] = $this->language->get('error_lastname'); } - if ((oc_strlen($this->request->post['email']) > 96) || !filter_var($this->request->post['email'], FILTER_VALIDATE_EMAIL)) { + if ((utf8_strlen($this->request->post['email']) > 96) || !filter_var($this->request->post['email'], FILTER_VALIDATE_EMAIL)) { $this->error['email'] = $this->language->get('error_email'); } - if ((oc_strlen($this->request->post['telephone']) < 3) || (oc_strlen($this->request->post['telephone']) > 32)) { + if ((utf8_strlen($this->request->post['telephone']) < 3) || (utf8_strlen($this->request->post['telephone']) > 32)) { $this->error['telephone'] = $this->language->get('error_telephone'); } - if ((oc_strlen(trim($this->request->post['address_1'])) < 3) || (oc_strlen(trim($this->request->post['address_1'])) > 128)) { + if ((utf8_strlen(trim($this->request->post['address_1'])) < 3) || (utf8_strlen(trim($this->request->post['address_1'])) > 128)) { $this->error['address_1'] = $this->language->get('error_address_1'); } - if ((oc_strlen(trim($this->request->post['city'])) < 2) || (oc_strlen(trim($this->request->post['city'])) > 128)) { + if ((utf8_strlen(trim($this->request->post['city'])) < 2) || (utf8_strlen(trim($this->request->post['city'])) > 128)) { $this->error['city'] = $this->language->get('error_city'); } @@ -3381,7 +4335,7 @@ private function validatePaymentAddress(): bool { $country_info = $this->model_localisation_country->getCountry($this->request->post['country_id']); - if ($country_info && $country_info['postcode_required'] && (oc_strlen(trim($this->request->post['postcode'])) < 2 || oc_strlen(trim($this->request->post['postcode'])) > 10)) { + if ($country_info && $country_info['postcode_required'] && (utf8_strlen(trim($this->request->post['postcode'])) < 2 || utf8_strlen(trim($this->request->post['postcode'])) > 10)) { $this->error['postcode'] = $this->language->get('error_postcode'); } @@ -3392,14 +4346,14 @@ private function validatePaymentAddress(): bool { if (!isset($this->request->post['zone_id']) || $this->request->post['zone_id'] == '' || !is_numeric($this->request->post['zone_id'])) { $this->error['zone'] = $this->language->get('error_zone'); } - + // Customer Group - if (isset($this->request->post['customer_group_id']) && is_array($this->config->get('config_customer_group_display')) && in_array($this->request->post['customer_group_id'], (array)$this->config->get('config_customer_group_display'))) { - $customer_group_id = (int)$this->request->post['customer_group_id']; + if (isset($this->request->post['customer_group_id']) && is_array($this->config->get('config_customer_group_display')) && in_array($this->request->post['customer_group_id'], $this->config->get('config_customer_group_display'))) { + $customer_group_id = $this->request->post['customer_group_id']; } else { - $customer_group_id = (int)$this->config->get('config_customer_group_id'); + $customer_group_id = $this->config->get('config_customer_group_id'); } - + // Custom field validation $this->load->model('account/custom_field'); @@ -3408,33 +4362,28 @@ private function validatePaymentAddress(): bool { foreach ($custom_fields as $custom_field) { if ($custom_field['required'] && empty($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']])) { $this->error['custom_field' . $custom_field['custom_field_id']] = sprintf($this->language->get('error_custom_field'), $custom_field['name']); - } elseif (($custom_field['type'] == 'text') && !empty($custom_field['validation']) && !filter_var($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => $custom_field['validation']]])) { - $this->error['custom_field' . $custom_field['custom_field_id']] = sprintf($this->language->get('error_custom_field'), $custom_field['name']); - } + } elseif (($custom_field['type'] == 'text') && !empty($custom_field['validation']) && !filter_var($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']], FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => $custom_field['validation'])))) { + $this->error['custom_field' . $custom_field['custom_field_id']] = sprintf($this->language->get('error_custom_field'), $custom_field['name']); + } } - + return !$this->error; } - - /** - * Validate Shipping Address - * - * @return bool - */ - private function validateShippingAddress(): bool { - if ((oc_strlen(trim($this->request->post['firstname'])) < 1) || (oc_strlen(trim($this->request->post['firstname'])) > 32)) { + + private function validateShippingAddress() { + if ((utf8_strlen(trim($this->request->post['firstname'])) < 1) || (utf8_strlen(trim($this->request->post['firstname'])) > 32)) { $this->error['firstname'] = $this->language->get('error_firstname'); } - if ((oc_strlen(trim($this->request->post['lastname'])) < 1) || (oc_strlen(trim($this->request->post['lastname'])) > 32)) { + if ((utf8_strlen(trim($this->request->post['lastname'])) < 1) || (utf8_strlen(trim($this->request->post['lastname'])) > 32)) { $this->error['lastname'] = $this->language->get('error_lastname'); } - if ((oc_strlen(trim($this->request->post['address_1'])) < 3) || (oc_strlen(trim($this->request->post['address_1'])) > 128)) { + if ((utf8_strlen(trim($this->request->post['address_1'])) < 3) || (utf8_strlen(trim($this->request->post['address_1'])) > 128)) { $this->error['address_1'] = $this->language->get('error_address_1'); } - if ((oc_strlen(trim($this->request->post['city'])) < 2) || (oc_strlen(trim($this->request->post['city'])) > 128)) { + if ((utf8_strlen(trim($this->request->post['city'])) < 2) || (utf8_strlen(trim($this->request->post['city'])) > 128)) { $this->error['city'] = $this->language->get('error_city'); } @@ -3442,7 +4391,7 @@ private function validateShippingAddress(): bool { $country_info = $this->model_localisation_country->getCountry($this->request->post['country_id']); - if ($country_info && $country_info['postcode_required'] && (oc_strlen(trim($this->request->post['postcode'])) < 2 || oc_strlen(trim($this->request->post['postcode'])) > 10)) { + if ($country_info && $country_info['postcode_required'] && (utf8_strlen(trim($this->request->post['postcode'])) < 2 || utf8_strlen(trim($this->request->post['postcode'])) > 10)) { $this->error['postcode'] = $this->language->get('error_postcode'); } @@ -3453,38 +4402,33 @@ private function validateShippingAddress(): bool { if (!isset($this->request->post['zone_id']) || $this->request->post['zone_id'] == '' || !is_numeric($this->request->post['zone_id'])) { $this->error['zone'] = $this->language->get('error_zone'); } - + // Customer Group - if (isset($this->request->post['customer_group_id']) && is_array($this->config->get('config_customer_group_display')) && in_array($this->request->post['customer_group_id'], (array)$this->config->get('config_customer_group_display'))) { - $customer_group_id = (int)$this->request->post['customer_group_id']; + if (isset($this->request->post['customer_group_id']) && is_array($this->config->get('config_customer_group_display')) && in_array($this->request->post['customer_group_id'], $this->config->get('config_customer_group_display'))) { + $customer_group_id = $this->request->post['customer_group_id']; } else { - $customer_group_id = (int)$this->config->get('config_customer_group_id'); + $customer_group_id = $this->config->get('config_customer_group_id'); } - + // Custom field validation $this->load->model('account/custom_field'); $custom_fields = $this->model_account_custom_field->getCustomFields($customer_group_id); foreach ($custom_fields as $custom_field) { - if ($custom_field['location'] == 'address') { + if ($custom_field['location'] == 'address') { if ($custom_field['required'] && empty($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']])) { $this->error['custom_field' . $custom_field['custom_field_id']] = sprintf($this->language->get('error_custom_field'), $custom_field['name']); - } elseif (($custom_field['type'] == 'text') && !empty($custom_field['validation']) && !filter_var($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => $custom_field['validation']]])) { + } elseif (($custom_field['type'] == 'text') && !empty($custom_field['validation']) && !filter_var($this->request->post['custom_field'][$custom_field['location']][$custom_field['custom_field_id']], FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => $custom_field['validation'])))) { $this->error['custom_field' . $custom_field['custom_field_id']] = sprintf($this->language->get('error_custom_field'), $custom_field['name']); } } } - + return !$this->error; } - - /** - * Validate Coupon - * - * @return bool - */ - private function validateCoupon(): bool { + + private function validateCoupon() { $this->load->model('extension/total/coupon'); $coupon_info = $this->model_extension_total_coupon->getCoupon($this->request->post['coupon']); @@ -3493,17 +4437,12 @@ private function validateCoupon(): bool { return true; } else { $this->session->data['error_warning'] = $this->language->get('error_coupon'); - + return false; } } - /** - * Validate Voucher - * - * @return bool - */ - private function validateVoucher(): bool { + private function validateVoucher() { $this->load->model('extension/total/voucher'); $voucher_info = $this->model_extension_total_voucher->getVoucher($this->request->post['voucher']); @@ -3512,17 +4451,12 @@ private function validateVoucher(): bool { return true; } else { $this->session->data['error_warning'] = $this->language->get('error_voucher'); - + return false; } } - /** - * Validate Reward - * - * @return bool - */ - private function validateReward(): bool { + private function validateReward() { $points = $this->customer->getRewardPoints(); $points_total = 0; @@ -3551,46 +4485,34 @@ private function validateReward(): bool { return true; } else { $this->session->data['error_warning'] = $error; - + return false; } } - - /** - * Is Apple - * - * @return bool - */ + private function isApple() { if (!empty($this->request->server['HTTP_USER_AGENT'])) { - $user_agent = $this->request->server['HTTP_USER_AGENT']; - - $apple_agents = ['ipod', 'iphone', 'ipad']; - - foreach ($apple_agents as $apple_agent) { - if (stripos($user_agent, $apple_agent)) { - return true; - } + $user_agent = strtolower($this->request->server['HTTP_USER_AGENT']); + + $apple_agents = array('ipod', 'iphone', 'ipad', 'apple'); + + foreach ($apple_agents as $apple_agent){ + if (stripos($user_agent, $apple_agent)) { + return true; + } } - } - + } + return false; } - - /** - * Unserialize - * - * @param string $str - * - * @return array - */ - private function unserialize(string $str): array { - $data = []; - + + private function unserialize($str) { + $data = array(); + $str = str_replace('&', '&', $str); - + parse_str($str, $data); - + return $data; } -} +} \ No newline at end of file diff --git a/upload/catalog/controller/extension/payment/paypal_applepay.php b/upload/catalog/controller/extension/payment/paypal_applepay.php index af351a2fd..fb370ec64 100644 --- a/upload/catalog/controller/extension/payment/paypal_applepay.php +++ b/upload/catalog/controller/extension/payment/paypal_applepay.php @@ -1,35 +1,22 @@ - */ - private array $error = []; - - /** - * Index - * - * @return string - */ - public function index(): string { +class ControllerExtensionPaymentPayPalApplePay extends Controller { + private $error = array(); + + public function index() { $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -38,80 +25,75 @@ public function index(): string { $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['checkout_mode'] = $setting['general']['checkout_mode']; $data['transaction_method'] = $setting['general']['transaction_method']; - - if ($setting['applepay_button']['status']) { - $data['applepay_button_status'] = $setting['applepay_button']['status']; + + if ($setting['applepay_button']['checkout']['status']) { + $data['applepay_button_status'] = $setting['applepay_button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; return $this->load->view('extension/payment/paypal/paypal_applepay', $data); } - + return ''; } - - /** - * Modal - * - * @return void - */ - public function modal(): void { + + public function modal() { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -119,59 +101,59 @@ public function modal(): void { $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['transaction_method'] = $setting['general']['transaction_method']; - - if ($setting['applepay_button']['status']) { - $data['applepay_button_status'] = $setting['applepay_button']['status']; + + if ($setting['applepay_button']['checkout']['status']) { + $data['applepay_button_status'] = $setting['applepay_button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; $this->response->setOutput($this->load->view('extension/payment/paypal/paypal_applepay_modal', $data)); } -} +} \ No newline at end of file diff --git a/upload/catalog/controller/extension/payment/paypal_googlepay.php b/upload/catalog/controller/extension/payment/paypal_googlepay.php index 458cf4a6a..6aef9a4d4 100644 --- a/upload/catalog/controller/extension/payment/paypal_googlepay.php +++ b/upload/catalog/controller/extension/payment/paypal_googlepay.php @@ -1,35 +1,22 @@ - */ - private array $error = []; - - /** - * Index - * - * @return string - */ - public function index(): string { +class ControllerExtensionPaymentPayPalGooglePay extends Controller { + private $error = array(); + + public function index() { $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -38,80 +25,75 @@ public function index(): string { $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['checkout_mode'] = $setting['general']['checkout_mode']; $data['transaction_method'] = $setting['general']['transaction_method']; - - if ($setting['googlepay_button']['status']) { - $data['googlepay_button_status'] = $setting['googlepay_button']['status']; + + if ($setting['googlepay_button']['checkout']['status']) { + $data['googlepay_button_status'] = $setting['googlepay_button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; return $this->load->view('extension/payment/paypal/paypal_googlepay', $data); } - + return ''; } - - /** - * Modal - * - * @return void - */ - public function modal(): void { + + public function modal() { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -119,59 +101,59 @@ public function modal(): void { $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['transaction_method'] = $setting['general']['transaction_method']; - - if ($setting['googlepay_button']['status']) { - $data['googlepay_button_status'] = $setting['googlepay_button']['status']; + + if ($setting['googlepay_button']['checkout']['status']) { + $data['googlepay_button_status'] = $setting['googlepay_button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; $this->response->setOutput($this->load->view('extension/payment/paypal/paypal_googlepay_modal', $data)); } -} +} \ No newline at end of file diff --git a/upload/catalog/controller/extension/payment/paypal_paylater.php b/upload/catalog/controller/extension/payment/paypal_paylater.php index c0cb16e80..c53a9e1e3 100644 --- a/upload/catalog/controller/extension/payment/paypal_paylater.php +++ b/upload/catalog/controller/extension/payment/paypal_paylater.php @@ -1,34 +1,22 @@ load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - - // Setting - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -37,81 +25,75 @@ public function index(): string { $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['checkout_mode'] = $setting['general']['checkout_mode']; $data['transaction_method'] = $setting['general']['transaction_method']; - + if ($setting['button']['checkout']['status']) { $data['button_status'] = $setting['button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; return $this->load->view('extension/payment/paypal/paypal_paylater', $data); } - + return ''; } - - /** - * Modal - * - * @return void - */ - public function modal(): void { + + public function modal() { $this->load->language('extension/payment/paypal'); - - // Setting - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $data['client_id'] = $this->config->get('payment_paypal_client_id'); $data['secret'] = $this->config->get('payment_paypal_secret'); $data['merchant_id'] = $this->config->get('payment_paypal_merchant_id'); @@ -119,59 +101,59 @@ public function modal(): void { $data['partner_id'] = $setting['partner'][$data['environment']]['partner_id']; $data['partner_attribution_id'] = $setting['partner'][$data['environment']]['partner_attribution_id']; $data['transaction_method'] = $setting['general']['transaction_method']; - + if ($setting['button']['checkout']['status']) { $data['button_status'] = $setting['button']['checkout']['status']; } - - require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $data['partner_id'], - 'client_id' => $data['client_id'], - 'secret' => $data['secret'], - 'environment' => $data['environment'], + + require_once DIR_SYSTEM .'library/paypal/paypal.php'; + + $paypal_info = array( + 'partner_id' => $data['partner_id'], + 'client_id' => $data['client_id'], + 'secret' => $data['secret'], + 'environment' => $data['environment'], 'partner_attribution_id' => $data['partner_attribution_id'] - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - + $data['client_token'] = $paypal->getClientToken(); - + if ($paypal->hasErrors()) { - $error_messages = []; - + $error_messages = array(); + $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + if (isset($error['details'][0]['description'])) { $error_messages[] = $error['details'][0]['description']; } elseif (isset($error['message'])) { $error_messages[] = $error['message']; } - + $this->model_extension_payment_paypal->log($error, $error['message']); } - + $this->error['warning'] = implode(' ', $error_messages); } if (!empty($this->error['warning'])) { $this->error['warning'] .= ' ' . sprintf($this->language->get('error_payment'), $this->url->link('information/contact', '', true)); - } + } - $data['error'] = $this->error; + $data['error'] = $this->error; $this->response->setOutput($this->load->view('extension/payment/paypal/paypal_paylater_modal', $data)); } -} +} \ No newline at end of file diff --git a/upload/catalog/controller/extension/recurring/paypal.php b/upload/catalog/controller/extension/recurring/paypal.php new file mode 100644 index 000000000..7fded88a1 --- /dev/null +++ b/upload/catalog/controller/extension/recurring/paypal.php @@ -0,0 +1,72 @@ +config->get('payment_paypal_status') && !empty($this->request->get['order_recurring_id'])) { + $this->load->language('extension/recurring/paypal'); + + $this->load->model('account/recurring'); + + $data['order_recurring_id'] = $this->request->get['order_recurring_id']; + + $order_recurring_info = $this->model_account_recurring->getOrderRecurring($data['order_recurring_id']); + + if ($order_recurring_info) { + $data['recurring_status'] = $order_recurring_info['status']; + + $data['info_url'] = str_replace('&', '&', $this->url->link('extension/recurring/paypal/getRecurringInfo', 'order_recurring_id=' . $data['order_recurring_id'], true)); + $data['enable_url'] = str_replace('&', '&', $this->url->link('extension/recurring/paypal/enableRecurring', '', true)); + $data['disable_url'] = str_replace('&', '&', $this->url->link('extension/recurring/paypal/disableRecurring', '', true)); + + $content = $this->load->view('extension/recurring/paypal', $data); + } + } + + return $content; + } + + public function getRecurringInfo() { + $this->response->setOutput($this->index()); + } + + public function enableRecurring() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_recurring_id'])) { + $this->load->language('extension/recurring/paypal'); + + $this->load->model('extension/payment/paypal'); + + $order_recurring_id = $this->request->post['order_recurring_id']; + + $this->model_extension_payment_paypal->editOrderRecurringStatus($order_recurring_id, 1); + + $data['success'] = $this->language->get('success_enable_recurring'); + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } + + public function disableRecurring() { + if ($this->config->get('payment_paypal_status') && !empty($this->request->post['order_recurring_id'])) { + $this->load->language('extension/recurring/paypal'); + + $this->load->model('extension/payment/paypal'); + + $order_recurring_id = $this->request->post['order_recurring_id']; + + $this->model_extension_payment_paypal->editOrderRecurringStatus($order_recurring_id, 2); + + $data['success'] = $this->language->get('success_disable_recurring'); + } + + $data['error'] = $this->error; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($data)); + } +} \ No newline at end of file diff --git a/upload/catalog/language/en-gb/extension/payment/paypal.php b/upload/catalog/language/en-gb/extension/payment/paypal.php index ff99099b3..15dd45822 100644 --- a/upload/catalog/language/en-gb/extension/payment/paypal.php +++ b/upload/catalog/language/en-gb/extension/payment/paypal.php @@ -1,102 +1,109 @@ contact us'; // Column -$_['column_image'] = 'Image'; -$_['column_name'] = 'Product Name'; -$_['column_model'] = 'Model'; -$_['column_quantity'] = 'Quantity'; -$_['column_price'] = 'Unit Price'; -$_['column_total'] = 'Total'; +$_['column_image'] = 'Image'; +$_['column_name'] = 'Product Name'; +$_['column_model'] = 'Model'; +$_['column_quantity'] = 'Quantity'; +$_['column_price'] = 'Unit Price'; +$_['column_total'] = 'Total'; // Entry -$_['entry_email'] = 'E-Mail'; -$_['entry_firstname'] = 'First Name'; -$_['entry_lastname'] = 'Last Name'; -$_['entry_telephone'] = 'Telephone'; -$_['entry_company'] = 'Company'; -$_['entry_address_1'] = 'Address 1'; -$_['entry_address_2'] = 'Address 2'; -$_['entry_postcode'] = 'Post Code'; -$_['entry_city'] = 'City'; -$_['entry_country'] = 'Country'; -$_['entry_zone'] = 'Region / State'; -$_['entry_card_number'] = 'Card Number'; -$_['entry_expiration_date'] = 'Expiration Date'; -$_['entry_cvv'] = 'CVV'; +$_['entry_email'] = 'E-Mail'; +$_['entry_firstname'] = 'First Name'; +$_['entry_lastname'] = 'Last Name'; +$_['entry_telephone'] = 'Telephone'; +$_['entry_company'] = 'Company'; +$_['entry_address_1'] = 'Address 1'; +$_['entry_address_2'] = 'Address 2'; +$_['entry_postcode'] = 'Post Code'; +$_['entry_city'] = 'City'; +$_['entry_country'] = 'Country'; +$_['entry_zone'] = 'Region / State'; +$_['entry_card_number'] = 'Card Number'; +$_['entry_expiration_date'] = 'Expiration Date'; +$_['entry_cvv'] = 'CVV'; +$_['entry_card_save'] = 'Save your card'; -// Buttons -$_['button_confirm'] = 'Confirm'; -$_['button_shipping'] = 'Update shipping'; -$_['button_pay'] = 'Pay with Card'; +// Button +$_['button_confirm'] = 'Confirm'; +$_['button_shipping'] = 'Update shipping'; +$_['button_pay'] = 'Pay with Card'; + +// Success +$_['success_order'] = 'Success: You have modified orders!'; // Error -$_['error_warning'] = 'Please check the form carefully for errors.'; -$_['error_stock'] = 'Products marked with *** are not available in the desired quantity or not in stock!'; -$_['error_minimum'] = 'Minimum order amount for %s is %s!'; -$_['error_required'] = '%s required!'; -$_['error_product'] = 'Warning: There are no products in your cart!'; -$_['error_subscription_required'] = 'Please select a subscription payment!'; -$_['error_unavailable'] = 'Please use the full checkout with this order!'; -$_['error_shipping'] = 'Warning: Shipping method required!'; -$_['error_no_shipping'] = 'Warning: No Shipping options are available.'; -$_['error_firstname'] = 'First Name must be between 1 and 32 characters!'; -$_['error_lastname'] = 'Last Name must be between 1 and 32 characters!'; -$_['error_email'] = 'E-Mail address does not appear to be valid!'; -$_['error_telephone'] = 'Telephone must be between 3 and 32 characters!'; -$_['error_password'] = 'Password must be between 4 and 20 characters!'; -$_['error_confirm'] = 'Password confirmation does not match password!'; -$_['error_address_1'] = 'Address 1 must be between 3 and 128 characters!'; -$_['error_city'] = 'City must be between 2 and 128 characters!'; -$_['error_postcode'] = 'Postcode must be between 2 and 10 characters!'; -$_['error_country'] = 'Please select a country!'; -$_['error_zone'] = 'Please select a region / state!'; -$_['error_agree'] = 'Warning: You must agree to the %s!'; -$_['error_address'] = 'Warning: You must select address!'; -$_['error_custom_field'] = '%s required!'; -$_['error_order_voided'] = 'We could not process your payment. All purchase units in the order are voided. Please contact us.'; -$_['error_order_completed'] = 'We could not process your payment. The payment was authorized or the authorized payment was captured for the order. Please contact us.'; -$_['error_authorization_captured'] = 'We could not process your payment. The authorized payment has one or more captures against it. The sum of these captured payments is greater than the amount of the original authorized payment. Please contact us.'; -$_['error_authorization_denied'] = 'We could not process the transaction with this card. The funds could not be captured. Please try a different funding source.'; -$_['error_authorization_expired'] = 'We could not process your payment. The authorized payment has expired. Please contact us.'; -$_['error_capture_declined'] = 'We could not process the transaction with this card. The funds could not be captured. Please try a different funding source.'; -$_['error_capture_failed'] = 'We could not process your payment. There was an error while capturing payment. Please contact us.'; -$_['error_3ds_failed_authentication'] = 'We could not process the transaction with this card. You may have failed the challenge or the device was not verified.'; -$_['error_3ds_rejected_authentication'] = 'We could not process the transaction with this card. 3D Secure authentication was skipped by you.'; -$_['error_3ds_attempted_authentication'] = 'We could not process the transaction with this card. Card is not enrolled in 3D Secure as card issuing bank is not participating in 3D Secure.'; -$_['error_3ds_unable_authentication'] = 'We could not process the transaction with this card. Issuing bank is not able to complete authentication.'; -$_['error_3ds_challenge_authentication'] = 'We could not process the transaction with this card. Challenge required for authentication.'; -$_['error_3ds_card_ineligible'] = 'We could not process the transaction with this card. Card type and issuing bank are not ready to complete a 3D Secure authentication.'; -$_['error_3ds_system_unavailable'] = 'We could not process the transaction with this card. An error occurred with the 3D Secure authentication system.'; -$_['error_3ds_system_bypassed'] = 'We could not process the transaction with this card. 3D Secure was skipped as authentication system did not require a challenge.'; -$_['error_payment'] = 'Please choose another payment method or contact us.'; -$_['error_timeout'] = 'Sorry, PayPal is currently busy. Please try again later!'; +$_['error_warning'] = 'Please check the form carefully for errors.'; +$_['error_stock'] = 'Products marked with *** are not available in the desired quantity or not in stock!'; +$_['error_minimum'] = 'Minimum order amount for %s is %s!'; +$_['error_required'] = '%s required!'; +$_['error_product'] = 'Warning: There are no products in your cart!'; +$_['error_recurring_required'] = 'Please select a payment recurring!'; +$_['error_unavailable'] = 'Please use the full checkout with this order!'; +$_['error_shipping'] = 'Warning: Shipping method required!'; +$_['error_no_shipping'] = 'Warning: No Shipping options are available.'; +$_['error_firstname'] = 'First Name must be between 1 and 32 characters!'; +$_['error_lastname'] = 'Last Name must be between 1 and 32 characters!'; +$_['error_email'] = 'E-Mail address does not appear to be valid!'; +$_['error_telephone'] = 'Telephone must be between 3 and 32 characters!'; +$_['error_password'] = 'Password must be between 4 and 20 characters!'; +$_['error_confirm'] = 'Password confirmation does not match password!'; +$_['error_address_1'] = 'Address 1 must be between 3 and 128 characters!'; +$_['error_city'] = 'City must be between 2 and 128 characters!'; +$_['error_postcode'] = 'Postcode must be between 2 and 10 characters!'; +$_['error_country'] = 'Please select a country!'; +$_['error_zone'] = 'Please select a region / state!'; +$_['error_agree'] = 'Warning: You must agree to the %s!'; +$_['error_address'] = 'Warning: You must select address!'; +$_['error_custom_field'] = '%s required!'; +$_['error_order_voided'] = 'We could not process your payment. All purchase units in the order are voided. Please contact us.'; +$_['error_order_completed'] = 'We could not process your payment. The payment was authorized or the authorized payment was captured for the order. Please contact us.'; +$_['error_authorization_captured'] = 'We could not process your payment. The authorized payment has one or more captures against it. The sum of these captured payments is greater than the amount of the original authorized payment. Please contact us.'; +$_['error_authorization_denied'] = 'We could not process the transaction with this card. The funds could not be captured. Please try a different funding source.'; +$_['error_authorization_expired'] = 'We could not process your payment. The authorized payment has expired. Please contact us.'; +$_['error_capture_declined'] = 'We could not process the transaction with this card. The funds could not be captured. Please try a different funding source.'; +$_['error_capture_failed'] = 'We could not process your payment. There was an error while capturing payment. Please contact us.'; +$_['error_3ds_failed_authentication'] = 'We could not process the transaction with this card. You may have failed the challenge or the device was not verified.'; +$_['error_3ds_rejected_authentication'] = 'We could not process the transaction with this card. 3D Secure authentication was skipped by you.'; +$_['error_3ds_attempted_authentication'] = 'We could not process the transaction with this card. Card is not enrolled in 3D Secure as card issuing bank is not participating in 3D Secure.'; +$_['error_3ds_unable_authentication'] = 'We could not process the transaction with this card. Issuing bank is not able to complete authentication.'; +$_['error_3ds_challenge_authentication'] = 'We could not process the transaction with this card. Challenge required for authentication.'; +$_['error_3ds_card_ineligible'] = 'We could not process the transaction with this card. Card type and issuing bank are not ready to complete a 3D Secure authentication.'; +$_['error_3ds_system_unavailable'] = 'We could not process the transaction with this card. An error occurred with the 3D Secure authentication system.'; +$_['error_3ds_system_bypassed'] = 'We could not process the transaction with this card. 3D Secure was skipped as authentication system did not require a challenge.'; +$_['error_payment'] = 'Please choose another payment method or contact us.'; +$_['error_timeout'] = 'Sorry, PayPal is currently busy. Please try again later!'; \ No newline at end of file diff --git a/upload/catalog/language/en-gb/extension/recurring/paypal.php b/upload/catalog/language/en-gb/extension/recurring/paypal.php index 25eff516a..56898d083 100644 --- a/upload/catalog/language/en-gb/extension/recurring/paypal.php +++ b/upload/catalog/language/en-gb/extension/recurring/paypal.php @@ -5,4 +5,4 @@ // Success $_['success_enable_recurring'] = 'Success: Recurring payment was enabled.'; -$_['success_disable_recurring'] = 'Success: Recurring payment was disabled.'; +$_['success_disable_recurring'] = 'Success: Recurring payment was disabled.'; \ No newline at end of file diff --git a/upload/catalog/model/extension/payment/paypal.php b/upload/catalog/model/extension/payment/paypal.php index 0daaf4763..82bac0e3f 100644 --- a/upload/catalog/model/extension/payment/paypal.php +++ b/upload/catalog/model/extension/payment/paypal.php @@ -1,28 +1,19 @@ $address - * - * @return array - */ - public function getMethods(array $address): array { - $method_data = []; - + + public function getMethod($address, $total) { + $method_data = array(); + $agree_status = $this->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); - if (!$this->config->get('payment_paypal_geo_zone_id')) { + if (($this->config->get('payment_paypal_total') > 0) && ($this->config->get('payment_paypal_total') > $total)) { + $status = false; + } elseif (!$this->config->get('payment_paypal_geo_zone_id')) { $status = true; } elseif ($query->num_rows) { $status = true; @@ -30,704 +21,696 @@ public function getMethods(array $address): array { $status = false; } - if ($status) { - $method_data = [ + if ($status) { + $method_data = array( 'code' => 'paypal', 'title' => $this->language->get('text_paypal_title'), 'terms' => '', 'sort_order' => $this->config->get('payment_paypal_sort_order') - ]; + ); } } return $method_data; } - - /** - * Has Product In Cart - * - * @param int $product_id - * @param array $option - * @param int $subscription_plan_id - * - * @return int - */ - public function hasProductInCart(int $product_id, array $option = [], int $subscription_plan_id = 0): int { - $query = $this->db->query("SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "cart` WHERE `api_id` = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND `customer_id` = '" . (int)$this->customer->getId() . "' AND `session_id` = '" . $this->db->escape($this->session->getId()) . "' AND `product_id` = '" . (int)$product_id . "' AND `subscription_plan_id` = '" . (int)$subscription_plan_id . "' AND `option` = '" . $this->db->escape(json_encode($option)) . "'"); - - return (int)$query->row['total']; + + public function hasProductInCart($product_id, $option = array(), $recurring_id = 0) { + $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "' AND product_id = '" . (int)$product_id . "' AND recurring_id = '" . (int)$recurring_id . "' AND `option` = '" . $this->db->escape(json_encode($option)) . "'"); + + return $query->row['total']; } - - /** - * Get Country By Code - * - * @param string $code - * - * @return array> - */ - public function getCountryByCode(string $code): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `iso_code_2` = '" . $this->db->escape($code) . "' AND `status` = '1'"); - + + public function getCountryByCode($code) { + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country WHERE iso_code_2 = '" . $this->db->escape($code) . "' AND status = '1'"); + return $query->row; } + + public function getZoneByCode($country_id, $code) { + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone WHERE country_id = '" . (int)$country_id . "' AND (code = '" . $this->db->escape($code) . "' OR name = '" . $this->db->escape($code) . "') AND status = '1'"); + + return $query->row; + } + + public function addPayPalCustomerToken($data) { + $sql = "INSERT INTO `" . DB_PREFIX . "paypal_checkout_integration_customer_token` SET"; + + $implode = array(); + + if (!empty($data['customer_id'])) { + $implode[] = "`customer_id` = '" . (int)$data['customer_id'] . "'"; + } + + if (!empty($data['payment_method'])) { + $implode[] = "`payment_method` = '" . $this->db->escape($data['payment_method']) . "'"; + } - /** - * Get Zone By Code - * - * @param int $country_id - * @param string $code - * - * @return array - */ - public function getZoneByCode(int $country_id, string $code): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE `country_id` = '" . (int)$country_id . "' AND (`code` = '" . $this->db->escape($code) . "' OR `name` = '" . $this->db->escape($code) . "') AND `status` = '1'"); + if (!empty($data['vault_id'])) { + $implode[] = "`vault_id` = '" . $this->db->escape($data['vault_id']) . "'"; + } + + if (!empty($data['vault_customer_id'])) { + $implode[] = "`vault_customer_id` = '" . $this->db->escape($data['vault_customer_id']) . "'"; + } + + if (!empty($data['card_type'])) { + $implode[] = "`card_type` = '" . $this->db->escape($data['card_type']) . "'"; + } + + if (!empty($data['card_nice_type'])) { + $implode[] = "`card_nice_type` = '" . $this->db->escape($data['card_nice_type']) . "'"; + } + + if (!empty($data['card_last_digits'])) { + $implode[] = "`card_last_digits` = '" . $this->db->escape($data['card_last_digits']) . "'"; + } + + if (!empty($data['card_expiry'])) { + $implode[] = "`card_expiry` = '" . $this->db->escape($data['card_expiry']) . "'"; + } + + if ($implode) { + $sql .= implode(", ", $implode); + } + + $this->db->query($sql); + } + + public function deletePayPalCustomerToken($customer_id, $payment_method, $vault_id) { + $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "' AND `vault_id` = '" . $this->db->escape($vault_id) . "'"); + } + + public function setPayPalCustomerMainToken($customer_id, $payment_method, $vault_id) { + $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_customer_token` SET `main_token_status` = '0' WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "'"); + $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_customer_token` SET `main_token_status` = '1' WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "' AND `vault_id` = '" . $this->db->escape($vault_id) . "'"); + } + + public function getPayPalCustomerMainToken($customer_id, $payment_method) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "' AND `main_token_status` = '1'"); + + if ($query->num_rows) { + return $query->row; + } else { + return array(); + } + } + + public function getPayPalCustomerToken($customer_id, $payment_method, $vault_id) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "' AND `vault_id` = '" . $this->db->escape($vault_id) . "'"); - return $query->row; + if ($query->num_rows) { + return $query->row; + } else { + return array(); + } } + + public function getPayPalCustomerTokens($customer_id, $payment_method = '') { + if ($payment_method) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "' AND `payment_method` = '" . $this->db->escape($payment_method) . "'"); + } else { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_customer_token` WHERE `customer_id` = '" . (int)$customer_id . "'"); + } - /** - * Add PayPal Order - * - * @param array $data - * - * @return void - */ - public function addPayPalOrder(array $data): void { + if ($query->num_rows) { + return $query->rows; + } else { + return array(); + } + } + + public function addPayPalOrder($data) { $sql = "INSERT INTO `" . DB_PREFIX . "paypal_checkout_integration_order` SET"; - $implode = []; - + $implode = array(); + if (!empty($data['order_id'])) { $implode[] = "`order_id` = '" . (int)$data['order_id'] . "'"; } - + + if (!empty($data['paypal_order_id'])) { + $implode[] = "`paypal_order_id` = '" . $this->db->escape($data['paypal_order_id']) . "'"; + } + if (!empty($data['transaction_id'])) { $implode[] = "`transaction_id` = '" . $this->db->escape($data['transaction_id']) . "'"; } - + if (!empty($data['transaction_status'])) { $implode[] = "`transaction_status` = '" . $this->db->escape($data['transaction_status']) . "'"; } - + if (!empty($data['payment_method'])) { $implode[] = "`payment_method` = '" . $this->db->escape($data['payment_method']) . "'"; } - + if (!empty($data['vault_id'])) { $implode[] = "`vault_id` = '" . $this->db->escape($data['vault_id']) . "'"; } - + if (!empty($data['vault_customer_id'])) { $implode[] = "`vault_customer_id` = '" . $this->db->escape($data['vault_customer_id']) . "'"; } - + + if (!empty($data['card_type'])) { + $implode[] = "`card_type` = '" . $this->db->escape($data['card_type']) . "'"; + } + + if (!empty($data['card_nice_type'])) { + $implode[] = "`card_nice_type` = '" . $this->db->escape($data['card_nice_type']) . "'"; + } + + if (!empty($data['card_last_digits'])) { + $implode[] = "`card_last_digits` = '" . $this->db->escape($data['card_last_digits']) . "'"; + } + + if (!empty($data['card_expiry'])) { + $implode[] = "`card_expiry` = '" . $this->db->escape($data['card_expiry']) . "'"; + } + + if (!empty($data['total'])) { + $implode[] = "`total` = '" . (float)$data['total'] . "'"; + } + + if (!empty($data['currency_code'])) { + $implode[] = "`currency_code` = '" . $this->db->escape($data['currency_code']) . "'"; + } + if (!empty($data['environment'])) { $implode[] = "`environment` = '" . $this->db->escape($data['environment']) . "'"; } - + + if (isset($data['tracking_number'])) { + $implode[] = "`tracking_number` = '" . $this->db->escape($data['tracking_number']) . "'"; + } + + if (isset($data['carrier_name'])) { + $implode[] = "`carrier_name` = '" . $this->db->escape($data['carrier_name']) . "'"; + } + if ($implode) { $sql .= implode(", ", $implode); } - + $this->db->query($sql); } - - /** - * Edit PayPal Order - * - * @param array $data - * - * @return void - */ - public function editPayPalOrder(array $data): void { + + public function editPayPalOrder($data) { $sql = "UPDATE `" . DB_PREFIX . "paypal_checkout_integration_order` SET"; - $implode = []; - + $implode = array(); + + if (!empty($data['paypal_order_id'])) { + $implode[] = "`paypal_order_id` = '" . $this->db->escape($data['paypal_order_id']) . "'"; + } + if (!empty($data['transaction_id'])) { $implode[] = "`transaction_id` = '" . $this->db->escape($data['transaction_id']) . "'"; } - + if (!empty($data['transaction_status'])) { $implode[] = "`transaction_status` = '" . $this->db->escape($data['transaction_status']) . "'"; } - + if (!empty($data['payment_method'])) { $implode[] = "`payment_method` = '" . $this->db->escape($data['payment_method']) . "'"; } - + if (!empty($data['vault_id'])) { $implode[] = "`vault_id` = '" . $this->db->escape($data['vault_id']) . "'"; } - + if (!empty($data['vault_customer_id'])) { $implode[] = "`vault_customer_id` = '" . $this->db->escape($data['vault_customer_id']) . "'"; } - + + if (!empty($data['card_type'])) { + $implode[] = "`card_type` = '" . $this->db->escape($data['card_type']) . "'"; + } + + if (!empty($data['card_nice_type'])) { + $implode[] = "`card_nice_type` = '" . $this->db->escape($data['card_nice_type']) . "'"; + } + + if (!empty($data['card_last_digits'])) { + $implode[] = "`card_last_digits` = '" . $this->db->escape($data['card_last_digits']) . "'"; + } + + if (!empty($data['card_expiry'])) { + $implode[] = "`card_expiry` = '" . $this->db->escape($data['card_expiry']) . "'"; + } + + if (!empty($data['total'])) { + $implode[] = "`total` = '" . (float)$data['total'] . "'"; + } + + if (!empty($data['currency_code'])) { + $implode[] = "`currency_code` = '" . $this->db->escape($data['currency_code']) . "'"; + } + if (!empty($data['environment'])) { $implode[] = "`environment` = '" . $this->db->escape($data['environment']) . "'"; } - + + if (isset($data['tracking_number'])) { + $implode[] = "`tracking_number` = '" . $this->db->escape($data['tracking_number']) . "'"; + } + + if (isset($data['carrier_name'])) { + $implode[] = "`carrier_name` = '" . $this->db->escape($data['carrier_name']) . "'"; + } + if ($implode) { $sql .= implode(", ", $implode); } $sql .= " WHERE `order_id` = '" . (int)$data['order_id'] . "'"; - + $this->db->query($sql); } - - /** - * Delete PayPal Order - * - * @param int $order_id - * - * @return void - */ - public function deletePayPalOrder(int $order_id): void { + + public function deletePayPalOrder($order_id) { $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `order_id` = '" . (int)$order_id . "'"); } - - /** - * Get PayPal Order - * - * @param int $order_id - * - * @return array - */ - public function getPayPalOrder(int $order_id): array { + + public function getPayPalOrder($order_id) { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `order_id` = '" . (int)$order_id . "'"); - + if ($query->num_rows) { return $query->row; } else { - return []; + return array(); } } - - /** - * Add PayPal Order Subscription - * - * @param array $data - * - * @return void - */ - public function addPayPalOrderSubscription(array $data): void { - $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_checkout_integration_subscription` SET `subscription_id` = '" . (int)$data['subscription_id'] . "', `order_id` = '" . (int)$data['order_id'] . "', `next_payment` = NOW(), `trial_end` = '" . $this->db->escape($data['trial_end']) . "', `subscription_end` = '" . $this->db->escape($data['subscription_end']) . "', `currency_code` = '" . $this->db->escape($data['currency_code']) . "', `total` = '" . $this->currency->format($data['amount'], $data['currency_code'], false, false) . "', `date_added` = NOW(), `date_modified` = NOW()"); + + public function getPayPalOrderByPayPalOrderId($paypal_order_id) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `paypal_order_id` = '" . $this->db->escape($paypal_order_id) . "'"); + + if ($query->num_rows) { + return $query->row; + } else { + return array(); + } } - - /** - * Edit PayPal Order Subscription Next Payment - * - * @param int $order_id - * @param string $next_payment - * - * @return void - */ - public function editPayPalOrderSubscriptionNextPayment(int $order_id, string $next_payment): void { - $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_subscription` SET `next_payment` = '" . $this->db->escape($next_payment) . "', `date_modified` = NOW() WHERE `order_id` = '" . (int)$order_id . "'"); + + public function addPayPalOrderRecurring($data) { + $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` SET `order_recurring_id` = '" . (int)$data['order_recurring_id'] . "', `order_id` = '" . (int)$data['order_id'] . "', `date_added` = NOW(), `date_modified` = NOW(), `next_payment` = NOW(), `trial_end` = '" . $data['trial_end'] . "', `subscription_end` = '" . $data['subscription_end'] . "', `currency_code` = '" . $this->db->escape($data['currency_code']) . "', `total` = '" . $this->currency->format($data['amount'], $data['currency_code'], false, false) . "'"); } - /** - * Delete PayPal Order Subscription - * - * @param int $order_id - * - * @return void - */ - public function deletePayPalOrderSubscription(int $order_id): void { - $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_order` WHERE `order_id` = '" . (int)$order_id . "'"); + public function editPayPalOrderRecurringNextPayment($order_recurring_id, $next_payment) { + $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` SET `next_payment` = '" . $next_payment . "', `date_modified` = NOW() WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); + } + + public function deletePayPalOrderRecurring($order_id) { + $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` WHERE `order_id` = '" . (int)$order_id . "'"); } - /** - * Get PayPal Order Subscription - * - * @param int $order_id - * - * @return array - */ - public function getPayPalOrderSubscription(int $order_id): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` WHERE `order_id` = '" . (int)$order_id . "'"); - + public function getPayPalOrderRecurring($order_recurring_id) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); + return $query->row; } - - /** - * Add Order Subscription - * - * @param int $order_id - * @param array $data - * - * @return int - */ - public function addOrderSubscription(int $order_id, array $data): int { - $this->db->query("INSERT INTO `" . DB_PREFIX . "order_subscription` SET `order_id` = '" . (int)$order_id . "', `product_id` = '" . (int)$data['subscription']['product_id'] . "', `order_product_id` = '" . (int)$data['subscription']['order_product_id'] . "', `subscription_plan_id` = '" . (int)$data['subscription']['subscription_plan_id'] . "', `frequency` = '" . $this->db->escape($data['subscription']['frequency']) . "', `cycle` = '" . (int)$data['subscription']['cycle'] . "', `duration` = '" . (int)$data['subscription']['duration'] . "', `price` = '" . (float)$data['subscription']['price'] . "', `tax` = '" . (float)$data['subscription']['tax'] . "', `trial_frequency` = '" . $this->db->escape($data['subscription']['trial_frequency']) . "', `trial_cycle` = '" . (int)$data['subscription']['trial_cycle'] . "', `trial_duration` = '" . (int)$data['subscription']['trial_duration'] . "', `trial_price` = '" . (float)$data['subscription']['trial_price'] . "'"); + + public function addOrderRecurring($order_id, $description, $data, $reference) { + $this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring` SET `order_id` = '" . (int)$order_id . "', `date_added` = NOW(), `status` = '1', `product_id` = '" . (int)$data['product_id'] . "', `product_name` = '" . $this->db->escape($data['name']) . "', `product_quantity` = '" . $this->db->escape($data['quantity']) . "', `recurring_id` = '" . (int)$data['recurring']['recurring_id'] . "', `recurring_name` = '" . $this->db->escape($data['name']) . "', `recurring_description` = '" . $this->db->escape($description) . "', `recurring_frequency` = '" . $this->db->escape($data['recurring']['frequency']) . "', `recurring_cycle` = '" . (int)$data['recurring']['cycle'] . "', `recurring_duration` = '" . (int)$data['recurring']['duration'] . "', `recurring_price` = '" . (float)$data['recurring']['price'] . "', `trial` = '" . (int)$data['recurring']['trial'] . "', `trial_frequency` = '" . $this->db->escape($data['recurring']['trial_frequency']) . "', `trial_cycle` = '" . (int)$data['recurring']['trial_cycle'] . "', `trial_duration` = '" . (int)$data['recurring']['trial_duration'] . "', `trial_price` = '" . (float)$data['recurring']['trial_price'] . "', `reference` = '" . $this->db->escape($reference) . "'"); return $this->db->getLastId(); } - - /** - * Edit Order Subscription Status - * - * @param int $order_id - * @param int $status - * - * @return void - */ - public function editOrderSubscriptionStatus(int $order_id, int $status): void { - $this->db->query("UPDATE `" . DB_PREFIX . "paypal_checkout_integration_subscription` SET `status` = '" . (int)$status . "' WHERE `order_id` = '" . (int)$order_id . "'"); + + public function editOrderRecurringStatus($order_recurring_id, $status) { + $this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = '" . (int)$status . "' WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); } + + public function deleteOrderRecurring($order_id) { + $query = $this->db->query("SELECT order_recurring_id FROM `" . DB_PREFIX . "order_recurring` WHERE order_id = '" . (int)$order_id . "'"); - /** - * Delete Order Subscription - * - * @param int $order_id - * - * @return void - */ - public function deleteOrderSubscription(int $order_id): void { - $query = $this->db->query("SELECT `order_id` FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` WHERE `order_id` = '" . (int)$order_id . "'"); - - foreach ($query->rows as $order_subscription) { - $this->deleteSubscriptionTransaction($order_subscription['order_id']); + foreach ($query->rows as $order_recurring) { + $this->deleteOrderRecurringTransaction($order_recurring['order_recurring_id']); } - - $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` WHERE `order_id` = '" . (int)$order_id . "'"); + + $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "order_recurring` WHERE `order_id` = '" . (int)$order_id . "'"); } + + public function getOrderRecurrings() { + $query = $this->db->query("SELECT `or`.`order_recurring_id` FROM `" . DB_PREFIX . "order_recurring` `or` JOIN `" . DB_PREFIX . "order` `o` USING(`order_id`) WHERE `o`.`payment_code` = 'paypal' AND `or`.`status` = '1'"); - /** - * Get Order Subscriptions - * - * @return array> - */ - public function getOrderSubscriptions(): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` `pcis` INNER JOIN `" . DB_PREFIX . "order` `o` ON (`o`.`order_id` = `pcis`.`order_id`) WHERE `pcis`.`payment_code` = 'paypal' AND `o`.`customer_id` = '" . (int)$this->customer->getId() . "'"); + $order_recurring_data = array(); - return $query->rows; + foreach ($query->rows as $order_recurring) { + $order_recurring_data[] = $this->getOrderRecurring($order_recurring['order_recurring_id']); + } + + return $order_recurring_data; } - /** - * Get Order Subscription - * - * @param int $order_id - * - * @return array - */ - public function getOrderSubscription(int $order_id): array { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_checkout_integration_subscription` WHERE `order_id` = '" . (int)$order_id . "'"); - + public function getOrderRecurring($order_recurring_id) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_recurring` WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); + return $query->row; } - /** - * Add Subscription Transaction - * - * @param array $data - * - * @return void - */ - public function addSubscriptionTransaction(array $data): void { - $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_checkout_integration_transaction` SET `order_id` = '" . (int)$data['order_id'] . "', `reference` = '" . $this->db->escape($data['reference']) . "', `type` = '" . (int)$data['type'] . "', `amount` = '" . (float)$data['amount'] . "', `date_added` = NOW()"); + public function addOrderRecurringTransaction($data) { + $this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$data['order_recurring_id'] . "', `reference` = '" . $this->db->escape($data['reference']) . "', `type` = '" . (int)$data['type'] . "', `amount` = '" . (float)$data['amount'] . "', `date_added` = NOW()"); } - - /** - * Delete Subscription Transaction - * - * @param int $order_id - * - * @return void - */ - public function deleteSubscriptionTransaction(int $order_id): void { - $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "paypal_checkout_integration_transaction` WHERE `order_id` = '" . (int)$order_id . "'"); + + public function deleteOrderRecurringTransaction($order_recurring_id) { + $query = $this->db->query("DELETE FROM `" . DB_PREFIX . "order_recurring_transaction` WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'"); } - - /** - * Subscription Payment - * - * @param array $item - * @param array $order_info - * @param array $paypal_order_data - * - * @return void - */ - public function subscriptionPayment(array $item, array $order_info, array $paypal_order_data): void { - $this->load->model('checkout/subscription'); - - $_config = new \Config(); + + public function recurringPayment($product_data, $order_data, $paypal_order_data) { + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $transaction_method = $setting['general']['transaction_method']; - - if ($item['subscription']['trial_status'] == 1) { - $price = $item['subscription']['trial_price']; - $trial_amt = $this->currency->format($this->tax->calculate($item['subscription']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'] . ' ' . $this->session->data['currency']; - $trial_text = sprintf($this->language->get('text_trial'), $trial_amt, $item['subscription']['trial_cycle'], $item['subscription']['trial_frequency'], $item['subscription']['trial_duration']); + + $recurring_name = $product_data['recurring']['name']; + + if ($product_data['recurring']['trial'] == 1) { + $price = $product_data['recurring']['trial_price']; + $trial_amt = $this->currency->format($this->tax->calculate($product_data['recurring']['trial_price'], $product_data['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $product_data['quantity'] . ' ' . $this->session->data['currency']; + $trial_text = sprintf($this->language->get('text_trial'), $trial_amt, $product_data['recurring']['trial_cycle'], $product_data['recurring']['trial_frequency'], $product_data['recurring']['trial_duration']); } else { - $price = $item['subscription']['price']; + $price = $product_data['recurring']['price']; $trial_text = ''; } + + $recurring_amt = $this->currency->format($this->tax->calculate($product_data['recurring']['price'], $product_data['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $product_data['quantity'] . ' ' . $this->session->data['currency']; + $recurring_description = $trial_text . sprintf($this->language->get('text_recurring'), $recurring_amt, $product_data['recurring']['cycle'], $product_data['recurring']['frequency']); - // Subscriptions - $description = ''; - - if ($item['subscription']) { - if ($item['subscription']['trial_status']) { - $trial_price = $this->currency->format($this->tax->calculate($item['subscription']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']); - $trial_cycle = $item['subscription']['trial_cycle']; - $trial_frequency = $this->language->get('text_' . $item['subscription']['trial_frequency']); - $trial_duration = $item['subscription']['trial_duration']; - - $description .= sprintf($this->language->get('text_subscription_trial'), $price ? $trial_price : '', $trial_cycle, $trial_frequency, $trial_duration); - } - - $price = $this->currency->format($this->tax->calculate($item['subscription']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']); - - $cycle = $item['subscription']['cycle']; - $frequency = $this->language->get('text_' . $item['subscription']['frequency']); - $duration = $item['subscription']['duration']; - - if ($duration) { - $description .= sprintf($this->language->get('text_subscription_duration'), $price ?: '', $cycle, $frequency, $duration); - } else { - $description .= sprintf($this->language->get('text_subscription_cancel'), $price ?: '', $cycle, $frequency); - } - } - - $next_payment = new \DateTime('now'); - $trial_end = new \DateTime('now'); - $subscription_end = new \DateTime('now'); - - if (($item['subscription']['trial_status'] == 1) && ($item['subscription']['trial_duration'] != 0)) { - $next_payment = $this->calculateSchedule($item['subscription']['trial_frequency'], $next_payment, $item['subscription']['trial_cycle']); - $trial_end = $this->calculateSchedule($item['subscription']['trial_frequency'], $trial_end, $item['subscription']['trial_cycle'] * $item['subscription']['trial_duration']); - } elseif ($item['subscription']['trial_status'] == 1) { - $next_payment = $this->calculateSchedule($item['subscription']['trial_frequency'], $next_payment, $item['subscription']['trial_cycle']); - $trial_end = new \DateTime('0000-00-00'); - } - - if (date_format($trial_end, 'Y-m-d H:i:s') > date_format($subscription_end, 'Y-m-d H:i:s') && $item['subscription']['duration'] != 0) { - $subscription_end = new \DateTime(date_format($trial_end, 'Y-m-d H:i:s')); - $subscription_end = $this->calculateSchedule($item['subscription']['frequency'], $subscription_end, $item['subscription']['cycle'] * $item['subscription']['duration']); - } elseif (date_format($trial_end, 'Y-m-d H:i:s') == date_format($subscription_end, 'Y-m-d H:i:s') && $item['subscription']['duration'] != 0) { - $next_payment = $this->calculateSchedule($item['subscription']['frequency'], $next_payment, $item['subscription']['cycle']); - $subscription_end = $this->calculateSchedule($item['subscription']['frequency'], $subscription_end, $item['subscription']['cycle'] * $item['subscription']['duration']); - } elseif (date_format($trial_end, 'Y-m-d H:i:s') > date_format($subscription_end, 'Y-m-d H:i:s') && $item['subscription']['duration'] == 0) { - $subscription_end = new \DateTime('0000-00-00'); - } elseif (date_format($trial_end, 'Y-m-d H:i:s') == date_format($subscription_end, 'Y-m-d H:i:s') && $item['subscription']['duration'] == 0) { - $next_payment = $this->calculateSchedule($item['subscription']['frequency'], $next_payment, $item['subscription']['cycle']); - $subscription_end = new \DateTime('0000-00-00'); + if ($product_data['recurring']['duration'] > 0) { + $recurring_description .= sprintf($this->language->get('text_length'), $product_data['recurring']['duration']); } - - $this->addOrderSubscription($this->session->data['order_id'], $item); - - $result = $this->createPayment($order_info, $paypal_order_data, $price, $item['subscription']['name']); - - $transaction_status = ''; - $transaction_id = ''; - $currency_code = ''; - $amount = ''; - - if ($transaction_method == 'authorize') { - if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { - $transaction_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; - $transaction_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; - $currency_code = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['currency_code']; - $amount = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['value']; + + $order_recurring_id = $this->addOrderRecurring($order_data['order_id'], $recurring_description, $product_data, $paypal_order_data['transaction_id']); + + $this->editOrderRecurringStatus($order_recurring_id, 1); + + if (!empty($paypal_order_data['vault_id'])) { + $next_payment = new DateTime('now'); + $trial_end = new DateTime('now'); + $subscription_end = new DateTime('now'); + + if (($product_data['recurring']['trial'] == 1) && ($product_data['recurring']['trial_duration'] != 0)) { + $next_payment = $this->calculateSchedule($product_data['recurring']['trial_frequency'], $next_payment, $product_data['recurring']['trial_cycle']); + $trial_end = $this->calculateSchedule($product_data['recurring']['trial_frequency'], $trial_end, $product_data['recurring']['trial_cycle'] * $product_data['recurring']['trial_duration']); + } elseif ($product_data['recurring']['trial'] == 1) { + $next_payment = $this->calculateSchedule($product_data['recurring']['trial_frequency'], $next_payment, $product_data['recurring']['trial_cycle']); + $trial_end = new DateTime('0000-00-00'); } - } else { - if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { - $transaction_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; - $transaction_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; - $currency_code = $result['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code']; - $amount = $result['purchase_units'][0]['payments']['captures'][0]['amount']['value']; + + if (date_format($trial_end, 'Y-m-d H:i:s') > date_format($subscription_end, 'Y-m-d H:i:s') && $product_data['recurring']['duration'] != 0) { + $subscription_end = new DateTime(date_format($trial_end, 'Y-m-d H:i:s')); + $subscription_end = $this->calculateSchedule($product_data['recurring']['frequency'], $subscription_end, $product_data['recurring']['cycle'] * $product_data['recurring']['duration']); + } elseif (date_format($trial_end, 'Y-m-d H:i:s') == date_format($subscription_end, 'Y-m-d H:i:s') && $product_data['recurring']['duration'] != 0) { + $next_payment = $this->calculateSchedule($product_data['recurring']['frequency'], $next_payment, $product_data['recurring']['cycle']); + $subscription_end = $this->calculateSchedule($product_data['recurring']['frequency'], $subscription_end, $product_data['recurring']['cycle'] * $product_data['recurring']['duration']); + } elseif (date_format($trial_end, 'Y-m-d H:i:s') > date_format($subscription_end, 'Y-m-d H:i:s') && $product_data['recurring']['duration'] == 0) { + $subscription_end = new DateTime('0000-00-00'); + } elseif (date_format($trial_end, 'Y-m-d H:i:s') == date_format($subscription_end, 'Y-m-d H:i:s') && $product_data['recurring']['duration'] == 0) { + $next_payment = $this->calculateSchedule($product_data['recurring']['frequency'], $next_payment, $product_data['recurring']['cycle']); + $subscription_end = new DateTime('0000-00-00'); } - } - - if ($transaction_id && $transaction_status && $currency_code && $amount) { - $this->editOrderSubscriptionStatus($order_info['order_id'], 1); - - $paypal_subscription_data = [ - 'subscription_id' => $item['subscription']['subscription_id'], - 'order_id' => $this->session->data['order_id'], - 'trial_end' => date_format($trial_end, 'Y-m-d H:i:s'), - 'subscription_end' => date_format($subscription_end, 'Y-m-d H:i:s'), - 'currency_code' => $currency_code, - 'amount' => $amount - ]; - - $this->addPayPalOrderSubscription($paypal_subscription_data); - - if (($transaction_status == 'CREATED') || ($transaction_status == 'COMPLETED') || ($transaction_status == 'PENDING')) { - $subscription_transaction_data = [ - 'subscription_id' => $item['subscription']['subscription_id'], - 'order_id' => $this->session->data['order_id'], - 'reference' => $transaction_id, - 'type' => '1', - 'amount' => $amount - ]; - - $this->addSubscriptionTransaction($subscription_transaction_data); - - $this->editPayPalOrderSubscriptionNextPayment($item['subscription']['subscription_id'], date_format($next_payment, 'Y-m-d H:i:s')); + + $result = $this->createPayment($order_data, $paypal_order_data, $price, $order_recurring_id, $recurring_name); + + $transaction_status = ''; + $transaction_id = ''; + $currency_code = ''; + $amount = ''; + + if ($transaction_method == 'authorize') { + if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { + $transaction_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; + $transaction_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; + $currency_code = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['currency_code']; + $amount = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['value']; + } } else { - $subscription_transaction_data = [ - 'subscription_id' => $item['subscription']['subscription_id'], - 'order_id' => $this->session->data['order_id'], - 'reference' => $transaction_id, - 'type' => '4', - 'amount' => $amount - ]; - - $this->addSubscriptionTransaction($subscription_transaction_data); + if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { + $transaction_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; + $transaction_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; + $currency_code = $result['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code']; + $amount = $result['purchase_units'][0]['payments']['captures'][0]['amount']['value']; + } + } + + if ($transaction_id && $transaction_status && $currency_code && $amount) { + $paypal_order_recurring_data = array( + 'order_recurring_id' => $order_recurring_id, + 'order_id' => $order_data['order_id'], + 'trial_end' => date_format($trial_end, 'Y-m-d H:i:s'), + 'subscription_end' => date_format($subscription_end, 'Y-m-d H:i:s'), + 'currency_code' => $currency_code, + 'amount' => $amount + ); + + $this->addPayPalOrderRecurring($paypal_order_recurring_data); + + if (($transaction_status == 'CREATED') || ($transaction_status == 'COMPLETED') || ($transaction_status == 'PENDING')) { + $order_recurring_transaction_data = array( + 'order_recurring_id' => $order_recurring_id, + 'reference' => $transaction_id, + 'type' => '1', + 'amount' => $amount + ); + + $this->addOrderRecurringTransaction($order_recurring_transaction_data); + + $this->editPayPalOrderRecurringNextPayment($order_recurring_id, date_format($next_payment, 'Y-m-d H:i:s')); + } else { + $order_recurring_transaction_data = array( + 'order_recurring_id' => $order_recurring_id, + 'reference' => $transaction_id, + 'type' => '4', + 'amount' => $amount + ); + + $this->addOrderRecurringTransaction($order_recurring_transaction_data); + } } } } - - /** - * Cron Payment - * - * @return void - */ - public function cronPayment(): void { - $this->load->model('account/subscription'); + + public function cronPayment() { $this->load->model('checkout/order'); - $this->load->model('account/order'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $transaction_method = $setting['general']['transaction_method']; - - $limit = $this->config->get('config_pagination'); - - $subscriptions = $this->model_account_subscription->getSubscriptions(0, $limit); - - foreach ($subscriptions as $subscription) { - $order_subscription = $this->model_account_subscription->getSubscriptionByOrderProductId($subscription['order_id'], $subscription['order_product_id']); - - if ($order_subscription && $order_subscription['status'] == 1) { - $paypal_order_subscription = $this->getPayPalOrderSubscription($order_subscription['order_id']); - - if ($paypal_order_subscription) { - $today = new \DateTime('now'); - $unlimited = new \DateTime('0000-00-00'); - $next_payment = new \DateTime($paypal_order_subscription['next_payment']); - $trial_end = new \DateTime($paypal_order_subscription['trial_end']); - $subscription_end = new \DateTime($paypal_order_subscription['subscription_end']); - - $order_info = $this->model_checkout_order->getOrder($order_subscription['order_id']); - - $order_product = $this->model_account_order->getProduct($order_subscription['order_id'], $order_subscription['order_product_id']); - - $paypal_order_info = $this->getPayPalOrder($order_subscription['order_id']); - - if ((date_format($today, 'Y-m-d H:i:s') > date_format($next_payment, 'Y-m-d H:i:s')) && (date_format($trial_end, 'Y-m-d H:i:s') > date_format($today, 'Y-m-d H:i:s') || date_format($trial_end, 'Y-m-d H:i:s') == date_format($unlimited, 'Y-m-d H:i:s'))) { - $price = $this->currency->format($order_subscription['trial_price'], $order_info['currency_code'], false, false); - $frequency = $order_subscription['trial_frequency']; - $cycle = $order_subscription['trial_cycle']; - $next_payment = $this->calculateSchedule($frequency, $next_payment, $cycle); - } elseif ((date_format($today, 'Y-m-d H:i:s') > date_format($next_payment, 'Y-m-d H:i:s')) && (date_format($subscription_end, 'Y-m-d H:i:s') > date_format($today, 'Y-m-d H:i:s') || date_format($subscription_end, 'Y-m-d H:i:s') == date_format($unlimited, 'Y-m-d H:i:s'))) { - $price = $this->currency->format($order_subscription['price'], $order_info['currency_code'], false, false); - $frequency = $order_subscription['frequency']; - $cycle = $order_subscription['cycle']; - $next_payment = $this->calculateSchedule($frequency, $next_payment, $cycle); - } else { - continue; - } - - $result = $this->createPayment($order_info, $paypal_order_info, $price, $order_product['name']); - - $transaction_status = ''; - $transaction_id = ''; - $currency_code = ''; - $amount = ''; - - if ($transaction_method == 'authorize') { - if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { - $transaction_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; - $transaction_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; - $currency_code = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['currency_code']; - $amount = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['value']; - } - } else { - if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { - $transaction_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; - $transaction_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; - $currency_code = $result['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code']; - $amount = $result['purchase_units'][0]['payments']['captures'][0]['amount']['value']; + + $order_recurrings = $this->getOrderRecurrings(); + + foreach ($order_recurrings as $order_recurring) { + if ($order_recurring['status'] == 1) { + $paypal_order_recurring = $this->getPayPalOrderRecurring($order_recurring['order_recurring_id']); + + if ($paypal_order_recurring) { + $today = new DateTime('now'); + $unlimited = new DateTime('0000-00-00'); + $next_payment = new DateTime($paypal_order_recurring['next_payment']); + $trial_end = new DateTime($paypal_order_recurring['trial_end']); + $subscription_end = new DateTime($paypal_order_recurring['subscription_end']); + + $order_info = $this->model_checkout_order->getOrder($order_recurring['order_id']); + + $paypal_order_info = $this->getPayPalOrder($order_recurring['order_id']); + + if (!empty($paypal_order_info['vault_id'])) { + if ((date_format($today, 'Y-m-d H:i:s') > date_format($next_payment, 'Y-m-d H:i:s')) && (date_format($trial_end, 'Y-m-d H:i:s') > date_format($today, 'Y-m-d H:i:s') || date_format($trial_end, 'Y-m-d H:i:s') == date_format($unlimited, 'Y-m-d H:i:s'))) { + $price = $this->currency->format($order_recurring['trial_price'], $order_info['currency_code'], false, false); + $frequency = $order_recurring['trial_frequency']; + $cycle = $order_recurring['trial_cycle']; + $next_payment = $this->calculateSchedule($frequency, $next_payment, $cycle); + } elseif ((date_format($today, 'Y-m-d H:i:s') > date_format($next_payment, 'Y-m-d H:i:s')) && (date_format($subscription_end, 'Y-m-d H:i:s') > date_format($today, 'Y-m-d H:i:s') || date_format($subscription_end, 'Y-m-d H:i:s') == date_format($unlimited, 'Y-m-d H:i:s'))) { + $price = $this->currency->format($order_recurring['recurring_price'], $order_info['currency_code'], false, false); + $frequency = $order_recurring['recurring_frequency']; + $cycle = $order_recurring['recurring_cycle']; + $next_payment = $this->calculateSchedule($frequency, $next_payment, $cycle); + } else { + continue; } - } - if ($transaction_id && $transaction_status && $currency_code && $amount) { - if (($transaction_status == 'CREATED') || ($transaction_status == 'COMPLETED') || ($transaction_status == 'PENDING')) { - $subscription_transaction_data = [ - 'subscription_id' => $subscription['subscription_id'], - 'reference' => $transaction_id, - 'type' => '1', - 'amount' => $amount - ]; - - $this->addSubscriptionTransaction($subscription_transaction_data); - - $this->editPayPalOrderSubscriptionNextPayment($order_subscription['order_id'], date_format($next_payment, 'Y-m-d H:i:s')); + $result = $this->createPayment($order_info, $paypal_order_info, $price, $order_recurring['order_recurring_id'], $order_recurring['recurring_name']); + + $transaction_status = ''; + $transaction_id = ''; + $currency_code = ''; + $amount = ''; + + if ($transaction_method == 'authorize') { + if (isset($result['purchase_units'][0]['payments']['authorizations'][0]['status']) && isset($result['purchase_units'][0]['payments']['authorizations'][0]['seller_protection']['status'])) { + $transaction_id = $result['purchase_units'][0]['payments']['authorizations'][0]['id']; + $transaction_status = $result['purchase_units'][0]['payments']['authorizations'][0]['status']; + $currency_code = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['currency_code']; + $amount = $result['purchase_units'][0]['payments']['authorizations'][0]['amount']['value']; + } } else { - $subscription_transaction_data = [ - 'subscription_id' => $subscription['subscription_id'], - 'reference' => $transaction_id, - 'type' => '4', - 'amount' => $amount - ]; - - $this->addSubscriptionTransaction($subscription_transaction_data); + if (isset($result['purchase_units'][0]['payments']['captures'][0]['status']) && isset($result['purchase_units'][0]['payments']['captures'][0]['seller_protection']['status'])) { + $transaction_id = $result['purchase_units'][0]['payments']['captures'][0]['id']; + $transaction_status = $result['purchase_units'][0]['payments']['captures'][0]['status']; + $currency_code = $result['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code']; + $amount = $result['purchase_units'][0]['payments']['captures'][0]['amount']['value']; + } + } + + if ($transaction_id && $transaction_status && $currency_code && $amount) { + if (($transaction_status == 'CREATED') || ($transaction_status == 'COMPLETED') || ($transaction_status == 'PENDING')) { + $order_recurring_transaction_data = array( + 'order_recurring_id' => $order_recurring['order_recurring_id'], + 'reference' => $transaction_id, + 'type' => '1', + 'amount' => $amount + ); + + $this->addOrderRecurringTransaction($order_recurring_transaction_data); + + $this->editPayPalOrderRecurringNextPayment($order_recurring['order_recurring_id'], date_format($next_payment, 'Y-m-d H:i:s')); + } else { + $order_recurring_transaction_data = array( + 'order_recurring_id' => $order_recurring['order_recurring_id'], + 'reference' => $transaction_id, + 'type' => '4', + 'amount' => $amount + ); + + $this->addOrderRecurringTransaction($order_recurring_transaction_data); + } } } } } } } - - /** - * Create Payment - * - * @param array $order_data - * @param array $paypal_order_data - * @param float $price - * @param string $name - * - * @return array - */ - public function createPayment(array $order_data, array $paypal_order_data, float $price, string $name): array { + + public function createPayment($order_data, $paypal_order_data, $price, $order_recurring_id, $recurring_name) { $this->load->language('extension/payment/paypal'); - - $_config = new \Config(); + + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + $client_id = $this->config->get('payment_paypal_client_id'); $secret = $this->config->get('payment_paypal_secret'); $merchant_id = $this->config->get('payment_paypal_merchant_id'); $environment = $this->config->get('payment_paypal_environment'); $partner_id = $setting['partner'][$environment]['partner_id']; $partner_attribution_id = $setting['partner'][$environment]['partner_attribution_id']; - $transaction_method = $setting['general']['transaction_method']; - + $transaction_method = $setting['general']['transaction_method']; + $currency_code = $order_data['currency_code']; - $currency_value = $this->currency->getValue($currency_code); + $currency_value = $this->currency->getValue($currency_code); $decimal_place = $setting['currency'][$currency_code]['decimal_place']; - + require_once DIR_SYSTEM . 'library/paypal/paypal.php'; - - $paypal_info = [ - 'partner_id' => $partner_id, - 'client_id' => $client_id, - 'secret' => $secret, - 'environment' => $environment, + + $paypal_info = array( + 'partner_id' => $partner_id, + 'client_id' => $client_id, + 'secret' => $secret, + 'environment' => $environment, 'partner_attribution_id' => $partner_attribution_id - ]; - + ); + $paypal = new PayPal($paypal_info); - - $token_info = [ + + $token_info = array( 'grant_type' => 'client_credentials' - ]; - + ); + $paypal->setAccessToken($token_info); - - $item_info = []; - + + $item_info = array(); + $item_total = 0; - + $product_price = number_format($price * $currency_value, $decimal_place, '.', ''); - - $item_info[] = [ - 'name' => $name, - 'quantity' => 1, - 'unit_amount' => [ + + $item_info[] = array( + 'name' => $recurring_name, + 'quantity' => 1, + 'unit_amount' => array( 'currency_code' => $currency_code, - 'value' => $product_price - ] - ]; - + 'value' => $product_price + ) + ); + $item_total += $product_price; - + $item_total = number_format($item_total, $decimal_place, '.', ''); $order_total = number_format($item_total, $decimal_place, '.', ''); - - $amount_info = []; - + + $amount_info = array(); + $amount_info['currency_code'] = $currency_code; $amount_info['value'] = $order_total; - - $amount_info['breakdown']['item_total'] = [ + + $amount_info['breakdown']['item_total'] = array( 'currency_code' => $currency_code, - 'value' => $item_total - ]; - - $paypal_order_info = []; - + 'value' => $item_total + ); + + $paypal_order_info = array(); + $paypal_order_info['intent'] = strtoupper($transaction_method); $paypal_order_info['purchase_units'][0]['reference_id'] = 'default'; $paypal_order_info['purchase_units'][0]['items'] = $item_info; $paypal_order_info['purchase_units'][0]['amount'] = $amount_info; - + $paypal_order_info['purchase_units'][0]['description'] = 'Subscription to order ' . $order_data['order_id']; - + $shipping_preference = 'NO_SHIPPING'; - + $paypal_order_info['application_context']['shipping_preference'] = $shipping_preference; - + $paypal_order_info['payment_source'][$paypal_order_data['payment_method']]['vault_id'] = $paypal_order_data['vault_id']; - + + if ($paypal_order_data['payment_method'] == 'card') { + $paypal_order_info['payment_source'][$paypal_order_data['payment_method']]['stored_credential']['payment_initiator'] = 'MERCHANT'; + $paypal_order_info['payment_source'][$paypal_order_data['payment_method']]['stored_credential']['payment_type'] = 'UNSCHEDULED'; + $paypal_order_info['payment_source'][$paypal_order_data['payment_method']]['stored_credential']['usage'] = 'SUBSEQUENT'; + $paypal_order_info['payment_source'][$paypal_order_data['payment_method']]['stored_credential']['previous_transaction_reference'] = $paypal_order_data['transaction_id']; + } + $result = $paypal->createOrder($paypal_order_info); - - $errors = []; - + + $errors = array(); + if ($paypal->hasErrors()) { $errors = $paypal->getErrors(); - + foreach ($errors as $error) { if (isset($error['name']) && ($error['name'] == 'CURLE_OPERATION_TIMEOUTED')) { $error['message'] = $this->language->get('error_timeout'); } - + $this->log($error, $error['message']); } } - + if (isset($result['id']) && isset($result['status']) && !$errors) { - $this->log($result, 'Create Subscription Payment'); - + $this->log($result, 'Create Recurring Payment'); + return $result; } - - return []; + + return false; } - - /** - * Calculate Schedule - * - * @param string $frequency - * @param \Datetime $next_payment - * @param int $cycle - * - * @return \Datetime - */ - private function calculateSchedule(string $frequency, \DateTime $next_payment, int $cycle) { - $next_payment = clone $next_payment; - + + public function calculateSchedule($frequency, $next_payment, $cycle) { if ($frequency == 'semi_month') { - $day = $next_payment->format('d'); + $day = date_format($next_payment, 'd'); $value = 15 - $day; $is_even = false; @@ -740,8 +723,8 @@ private function calculateSchedule(string $frequency, \DateTime $next_payment, i $minus_even = $cycle / 2; if ($day == 1) { - $odd--; - $plus_even--; + $odd = $odd - 1; + $plus_even = $plus_even - 1; $day = 16; } @@ -761,71 +744,101 @@ private function calculateSchedule(string $frequency, \DateTime $next_payment, i } else { $next_payment->modify('+' . $cycle . ' ' . $frequency); } - + return $next_payment; } - - /** - * Get Agree Status - * - * @return bool - */ - public function getAgreeStatus(): bool { + + public function getAgreeStatus() { $agree_status = true; - - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `status` = '1' AND (`iso_code_2` = 'CU' OR `iso_code_2` = 'IR' OR `iso_code_2` = 'SY' OR `iso_code_2` = 'KP')"); - + + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country WHERE status = '1' AND (iso_code_2 = 'CU' OR iso_code_2 = 'IR' OR iso_code_2 = 'SY' OR iso_code_2 = 'KP')"); + if ($query->rows) { $agree_status = false; } - - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE `country_id` = '220' AND `status` = '1' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); - + + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone WHERE country_id = '220' AND status = '1' AND (`code` = '43' OR `code` = '14' OR `code` = '09')"); + if ($query->rows) { $agree_status = false; } - + return $agree_status; } - - /** - * Log - * - * @param array $data - * @param ?string $title - * - * @return void - */ - public function log(array $data, ?string $title = ''): void { + + public function log($data, $title = '') { // Setting - $_config = new \Config(); + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + if ($setting['general']['debug']) { - $log = new \Log('paypal.log'); + $log = new Log('paypal.log'); $log->write('PayPal debug (' . $title . '): ' . json_encode($data)); } } + + public function update() { + if ($this->config->get('paypal_version') < '3.0.0') { + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order`"); + $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring`"); + + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_customer_token` (`customer_id` INT(11) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `main_token_status` TINYINT(1) NOT NULL, PRIMARY KEY (`customer_id`, `payment_method`, `vault_id`), KEY `vault_customer_id` (`vault_customer_id`), KEY `main_token_status` (`main_token_status`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order` (`order_id` INT(11) NOT NULL, `paypal_order_id` VARCHAR(20) NOT NULL, `transaction_id` VARCHAR(20) NOT NULL, `transaction_status` VARCHAR(20) NOT NULL, `payment_method` VARCHAR(20) NOT NULL, `vault_id` VARCHAR(50) NOT NULL, `vault_customer_id` VARCHAR(50) NOT NULL, `card_type` VARCHAR(40) NOT NULL, `card_nice_type` VARCHAR(40) NOT NULL, `card_last_digits` VARCHAR(4) NOT NULL, `card_expiry` VARCHAR(20) NOT NULL, `total` DECIMAL(15,2) NOT NULL, `currency_code` VARCHAR(3) NOT NULL, `environment` VARCHAR(20) NOT NULL, `tracking_number` VARCHAR(64) NOT NULL, `carrier_name` VARCHAR(64) NOT NULL, PRIMARY KEY (`order_id`), KEY `paypal_order_id` (`paypal_order_id`), KEY `transaction_id` (`transaction_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_checkout_integration_order_recurring` (`paypal_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT, `order_id` INT(11) NOT NULL, `order_recurring_id` INT(11) NOT NULL, `date_added` DATETIME NOT NULL, `date_modified` DATETIME NOT NULL, `next_payment` DATETIME NOT NULL, `trial_end` DATETIME DEFAULT NULL, `subscription_end` DATETIME DEFAULT NULL, `currency_code` CHAR(3) NOT NULL, `total` DECIMAL(10, 2) NOT NULL, PRIMARY KEY (`paypal_order_recurring_id`), KEY (`order_id`), KEY (`order_recurring_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"); + } elseif ($this->config->get('paypal_version') < '3.1.0') { + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `total` DECIMAL(15,2) NOT NULL AFTER `card_expiry`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `currency_code` VARCHAR(3) NOT NULL AFTER `total`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `tracking_number` VARCHAR(64) NOT NULL AFTER `environment`"); + $this->db->query("ALTER TABLE `" . DB_PREFIX . "paypal_checkout_integration_order` ADD COLUMN `carrier_name` VARCHAR(64) NOT NULL AFTER `tracking_number`"); + } + + $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = 'paypal_order_info'"); + $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = 'paypal_header'"); + $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = 'paypal_extension_get_extensions'"); + $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = 'paypal_order_delete_order'"); + $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = 'paypal_customer_delete_customer'"); + + $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = 'paypal_order_info', `trigger` = 'admin/view/sale/order_info/before', `action` = 'extension/payment/paypal/order_info_before', `sort_order` = '0', `status` = '1'"); + $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = 'paypal_header', `trigger` = 'catalog/controller/common/header/before', `action` = 'extension/payment/paypal/header_before', `sort_order` = '0', `status` = '1'"); + $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = 'paypal_extension_get_extensions', `trigger` = 'catalog/model/setting/extension/getExtensions/after', `action` = 'extension/payment/paypal/extension_get_extensions_after', `sort_order` = '0', `status` = '1'"); + $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = 'paypal_order_delete_order', `trigger` = 'catalog/model/checkout/order/deleteOrder/before', `action` = 'extension/payment/paypal/order_delete_order_before', `sort_order` = '0', `status` = '1'"); + $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = 'paypal_customer_delete_customer', `trigger` = 'admin/model/customer/customer/deleteCustomer/before', `action` = 'extension/payment/paypal/customer_delete_customer_before', `sort_order` = '0', `status` = '1'"); + + if ($this->config->get('paypal_version') < '3.1.0') { + $setting = array(); + + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "setting` WHERE store_id = '0' AND `key` = 'payment_paypal_setting'"); + + if ($query->row) { + $setting[$query->row['key']] = json_decode($query->row['value'], true); + } + + $setting['payment_paypal_setting']['general']['order_history_token'] = sha1(uniqid(mt_rand(), 1)); + + $this->db->query("UPDATE " . DB_PREFIX . "setting SET `value` = '" . $this->db->escape(json_encode($setting)) . "', serialized = '1' WHERE `key` = '" . $this->db->escape('payment_paypal_setting') . "' AND store_id = '0'"); + } + + // Setting + $_config = new Config(); + $_config->load('paypal'); + + $config_setting = $_config->get('paypal_setting'); + + $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE store_id = '0' AND `code` = 'paypal_version'"); - /** - * Charge - * - * @param int $customer_id - * @param int $order_id - * @param float $total - * @param string $payment_code - * - * @return bool - */ - public function charge(int $customer_id, int $order_id, float $total, string $payment_code): bool { + $this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '0', `code` = 'paypal_version', `key` = 'paypal_version', `value` = '" . $this->db->escape($config_setting['version']) . "'"); + } + + public function recurringPayments() { /* * Used by the checkout to state the module - * supports recurring subscriptions. + * supports recurring recurrings. */ return true; } -} +} \ No newline at end of file diff --git a/upload/catalog/model/extension/payment/paypal_applepay.php b/upload/catalog/model/extension/payment/paypal_applepay.php index 3d44d9568..df387171e 100644 --- a/upload/catalog/model/extension/payment/paypal_applepay.php +++ b/upload/catalog/model/extension/payment/paypal_applepay.php @@ -1,25 +1,21 @@ $address - * - * @return array - */ - public function getMethods(array $address): array { - $method_data = []; - +class ModelExtensionPaymentPayPalApplePay extends Model { + + public function getMethod($address, $total) { + $method_data = array(); + $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); - if (!$this->config->get('payment_paypal_geo_zone_id')) { + if (($this->config->get('payment_paypal_total') > 0) && ($this->config->get('payment_paypal_total') > $total)) { + $status = false; + } elseif (!$this->config->get('payment_paypal_geo_zone_id')) { $status = true; } elseif ($query->num_rows) { $status = true; @@ -27,16 +23,16 @@ public function getMethods(array $address): array { $status = false; } - if ($status) { - $method_data = [ + if ($status) { + $method_data = array( 'code' => 'paypal_applepay', 'title' => $this->language->get('text_paypal_applepay_title'), 'terms' => '', 'sort_order' => $this->config->get('payment_paypal_sort_order') - ]; + ); } } return $method_data; } -} +} \ No newline at end of file diff --git a/upload/catalog/model/extension/payment/paypal_googlepay.php b/upload/catalog/model/extension/payment/paypal_googlepay.php index b947707db..a1a7e91e7 100644 --- a/upload/catalog/model/extension/payment/paypal_googlepay.php +++ b/upload/catalog/model/extension/payment/paypal_googlepay.php @@ -1,25 +1,21 @@ $address - * - * @return array - */ - public function getMethods(array $address): array { - $method_data = []; - +class ModelExtensionPaymentPayPalGooglePay extends Model { + + public function getMethod($address, $total) { + $method_data = array(); + $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); - if (!$this->config->get('payment_paypal_geo_zone_id')) { + if (($this->config->get('payment_paypal_total') > 0) && ($this->config->get('payment_paypal_total') > $total)) { + $status = false; + } elseif (!$this->config->get('payment_paypal_geo_zone_id')) { $status = true; } elseif ($query->num_rows) { $status = true; @@ -28,15 +24,15 @@ public function getMethods(array $address): array { } if ($status) { - $method_data = [ + $method_data = array( 'code' => 'paypal_googlepay', 'title' => $this->language->get('text_paypal_googlepay_title'), 'terms' => '', 'sort_order' => $this->config->get('payment_paypal_sort_order') - ]; + ); } } return $method_data; } -} +} \ No newline at end of file diff --git a/upload/catalog/model/extension/payment/paypal_paylater.php b/upload/catalog/model/extension/payment/paypal_paylater.php index 19587e81c..668e4289e 100644 --- a/upload/catalog/model/extension/payment/paypal_paylater.php +++ b/upload/catalog/model/extension/payment/paypal_paylater.php @@ -1,30 +1,21 @@ $address - * - * @return array - */ - public function getMethods(array $address): array { - $method_data = []; - +class ModelExtensionPaymentPayPalPayLater extends Model { + + public function getMethod($address, $total) { + $method_data = array(); + $this->load->model('extension/payment/paypal'); - + $agree_status = $this->model_extension_payment_paypal->getAgreeStatus(); - + if ($this->config->get('payment_paypal_status') && $this->config->get('payment_paypal_client_id') && $this->config->get('payment_paypal_secret') && $agree_status) { $this->load->language('extension/payment/paypal'); - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('payment_paypal_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); - if (!$this->config->get('payment_paypal_geo_zone_id')) { + if (($this->config->get('payment_paypal_total') > 0) && ($this->config->get('payment_paypal_total') > $total)) { + $status = false; + } elseif (!$this->config->get('payment_paypal_geo_zone_id')) { $status = true; } elseif ($query->num_rows) { $status = true; @@ -34,28 +25,28 @@ public function getMethods(array $address): array { if ($status) { // Setting - $_config = new \Config(); + $_config = new Config(); $_config->load('paypal'); - + $config_setting = $_config->get('paypal_setting'); - + $setting = array_replace_recursive((array)$config_setting, (array)$this->config->get('payment_paypal_setting')); - + if ($setting['message']['checkout']['status'] && ($this->session->data['currency'] == $setting['general']['currency_code'])) { $message = $this->load->view('extension/payment/paypal/message'); } else { $message = ''; } - - $method_data = [ + + $method_data = array( 'code' => 'paypal_paylater', 'title' => $this->language->get('text_paypal_paylater_title') . $message, 'terms' => '', 'sort_order' => $this->config->get('payment_paypal_sort_order') - ]; + ); } } return $method_data; } -} +} \ No newline at end of file diff --git a/upload/catalog/view/javascript/paypal/paypal.js b/upload/catalog/view/javascript/paypal/paypal.js index 1e2e7407b..d74b511b4 100644 --- a/upload/catalog/view/javascript/paypal/paypal.js +++ b/upload/catalog/view/javascript/paypal/paypal.js @@ -3,10 +3,10 @@ var PayPalAPI = (function () { var paypal_script = []; var paypal_sdk = []; var paypal_callback; - + var showPayPalAlert = function(data) { $('.alert-dismissible').remove(); - + if (data['error'] && data['error']['warning']) { if ($('#paypal_form').length) { $('#paypal_form').prepend('
' + data['error']['warning'] + '
'); @@ -17,33 +17,37 @@ var PayPalAPI = (function () { } } }; - + var getQueryParams = function(url) { const param_arr = url.slice(url.indexOf('?') + 1).split('&'); const params = {}; - + param_arr.map(param => { const [key, val] = param.split('='); params[key] = decodeURIComponent(val); }) - + return params; }; - + var updatePayPalData = function() { var params = []; var script_file = document.getElementsByTagName('script'); - + for (var i = 0; i < script_file.length; i++) { if (script_file[i].hasAttribute('src') && (script_file[i].getAttribute('src').indexOf('paypal.js') !== -1)) { params = getQueryParams(script_file[i].getAttribute('src')); - + break; } } - + paypal_data = params; - + + if (paypal_data['page_code'] == 'product') { + paypal_data['product'] = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); + } + $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/getData', @@ -52,7 +56,7 @@ var PayPalAPI = (function () { async: false, success: function(json) { paypal_data = json; - + showPayPalAlert(json); }, error: function(xhr, ajaxOptions, thrownError) { @@ -60,29 +64,49 @@ var PayPalAPI = (function () { } }); }; - + var readyPayPalSDK = function() { if (typeof PayPalSDK === 'undefined') { setTimeout(readyPayPalSDK, 100); } else { paypal_sdk[paypal_script.length - 1] = PayPalSDK; - + initPayPalSDK(); } }; - + var loadPayPalSDK = function() { var html = ''; if (paypal_data['components'].includes('buttons')) { if (!$('#paypal_button').length) { if ($(paypal_data['button_insert_tag']).length) { - html = '
'; + html = '
'; eval("$('" + paypal_data['button_insert_tag'] + "')." + paypal_data['button_insert_type'] + "(html)"); } } } + + if (paypal_data['components'].includes('googlepay')) { + if (!$('#googlepay_button').length) { + if ($(paypal_data['googlepay_button_insert_tag']).length) { + html = '
'; + + eval("$('" + paypal_data['googlepay_button_insert_tag'] + "')." + paypal_data['googlepay_button_insert_type'] + "(html)"); + } + } + } + + if (paypal_data['components'].includes('applepay')) { + if (!$('#applepay_button').length) { + if ($(paypal_data['applepay_button_insert_tag']).length) { + html = '
'; + + eval("$('" + paypal_data['applepay_button_insert_tag'] + "')." + paypal_data['applepay_button_insert_type'] + "(html)"); + } + } + } if (paypal_data['components'].includes('messages')) { if (!$('#paypal_message').length) { @@ -95,18 +119,17 @@ var PayPalAPI = (function () { } var src_data = {}; - + src_data['components'] = paypal_data['components'].join(','); src_data['client-id'] = paypal_data['client_id']; src_data['merchant-id'] = paypal_data['merchant_id']; src_data['currency'] = paypal_data['currency_code']; src_data['intent'] = paypal_data['transaction_method']; - src_data['locale'] = paypal_data['locale']; - + if (paypal_data['button_enable_funding'] && paypal_data['button_enable_funding'].length) { src_data['enable-funding'] = paypal_data['button_enable_funding'].join(','); } - + if (paypal_data['button_disable_funding'] && paypal_data['button_disable_funding'].length) { src_data['disable-funding'] = paypal_data['button_disable_funding'].join(','); } @@ -133,8 +156,12 @@ var PayPalAPI = (function () { paypal_script[script_count].src = src; paypal_script[script_count].setAttribute('data-partner-attribution-id', paypal_data['partner_attribution_id']); paypal_script[script_count].setAttribute('data-client-token', paypal_data['client_token']); - paypal_script[script_count].setAttribute('data-namespace', 'PayPalSDK'); + paypal_script[script_count].setAttribute('data-namespace', 'PayPalSDK'); + if (paypal_data['id_token']) { + paypal_script[script_count].setAttribute('data-user-id-token', paypal_data['id_token']); + } + paypal_script[script_count].async = false; paypal_script[script_count].onload = readyPayPalSDK(); @@ -163,23 +190,25 @@ var PayPalAPI = (function () { env: paypal_data['environment'], locale: paypal_data['locale'], style: { - layout: ((paypal_data['page_code'] != 'checkout') ? 'horizontal' : 'vertical'), + layout: 'vertical', size: paypal_data['button_size'], color: paypal_data['button_color'], shape: paypal_data['button_shape'], label: paypal_data['button_label'], - tagline: ((paypal_data['page_code'] != 'checkout') ? paypal_data['button_tagline'] : 'false') + tagline: 'false' }, - // Set up the transaction - createOrder: function(data, actions) { + createOrder: function() { paypal_order_id = false; + product_data = false; - product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); + if (paypal_data['page_code'] == 'product') { + product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); + } $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/createOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'button', 'product' : product_data}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'button', 'product': product_data}, dataType: 'json', async: false, success: function(json) { @@ -194,23 +223,15 @@ var PayPalAPI = (function () { return paypal_order_id; }, - // Finalize the transaction - onApprove: function(data, actions) { - // Call your server to save the transaction - restart = false; - + onApprove: function(data) { $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/approveOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'button', 'paypal_order_id': data.orderID}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'button', 'paypal_order_id': data.orderID}, dataType: 'json', async: false, success: function(json) { showPayPalAlert(json); - - if (json['restart']) { - restart = json['restart']; - } if (json['url']) { location = json['url']; @@ -220,10 +241,6 @@ var PayPalAPI = (function () { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); - - if (restart) { - return actions.restart(); - } } }; @@ -265,7 +282,95 @@ var PayPalAPI = (function () { } } - if (paypal_data['components'].includes('hosted-fields') && $('#paypal_card').length && !$('#paypal_card_form').find('iframe').length) { + if (paypal_data['card_customer_tokens'] && $('#paypal_card_tokens').length && !$('#paypal_card_tokens_container').html()) { + $('#paypal_card_tokens').css('text-align', paypal_data['card_align']); + + if (paypal_data['card_width']) { + $('#paypal_card_tokens_container').css('display', 'inline-block'); + $('#paypal_card_tokens_container').css('width', paypal_data['card_width']); + } else { + $('#paypal_card_tokens_container').css('display', 'block'); + $('#paypal_card_tokens_container').css('width', 'auto'); + } + + $.each(paypal_data['card_customer_tokens'], function(index, card_customer_token) { + html = '
' + card_customer_token['card_number'] + '
'; + + $('#paypal_card_tokens_container').append(html); + }); + + $('#paypal_card_tokens_container').delegate('.card-token-button', 'click', function(event) { + event.preventDefault(); + + if (!$('#paypal_card_tokens_container').hasClass('disabled')) { + var paypal_card_token = $(this).parents('.paypal-card-token'); + var card_token_index = $(this).attr('index'); + + paypal_order_id = false; + + $.ajax({ + method: 'post', + url: 'index.php?route=extension/payment/paypal/createOrder', + data: {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'index': card_token_index}, + dataType: 'json', + beforeSend: function() { + paypal_card_token.addClass('paypal-spinner'); + $('#paypal_card_tokens_container').addClass('disabled'); + }, + success: function(json) { + showPayPalAlert(json); + + if (json['url']) { + location = json['url']; + } + }, + complete: function() { + paypal_card_token.removeClass('paypal-spinner'); + $('#paypal_card_tokens_container').removeClass('disabled'); + }, + error: function(xhr, ajaxOptions, thrownError) { + console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); + } + }); + } + }); + + $('#paypal_card_tokens_container').delegate('.card-token-delete-button', 'click', function(event) { + event.preventDefault(); + + if (!$('#paypal_card_tokens_container').hasClass('disabled')) { + var paypal_card_token = $(this).parents('.paypal-card-token'); + var card_token_index = $(this).attr('index'); + + $.ajax({ + method: 'post', + url: 'index.php?route=extension/payment/paypal/deleteCustomerToken', + data: {'index': card_token_index}, + dataType: 'json', + beforeSend: function() { + paypal_card_token.addClass('paypal-spinner'); + $('#paypal_card_tokens_container').addClass('disabled'); + }, + success: function(json) { + showPayPalAlert(json); + + if (json['success']) { + paypal_card_token.remove(); + } + }, + error: function(xhr, ajaxOptions, thrownError) { + console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); + }, + complete: function() { + paypal_card_token.removeClass('paypal-spinner'); + $('#paypal_card_tokens_container').removeClass('disabled'); + } + }); + } + }); + } + + if (paypal_data['components'].includes('card-fields') && $('#paypal_card').length && !$('#paypal_card_form').find('iframe').length) { $('#paypal_card').css('text-align', paypal_data['card_align']); if (paypal_data['card_width']) { @@ -277,171 +382,126 @@ var PayPalAPI = (function () { } try { - // Check if card fields are eligible to render for the buyer's country. The card fields are not eligible in all countries where buyers are located. - if (PayPalSDK.HostedFields.isEligible() === true) { - var paypal_card_form = document.querySelector('#paypal_card_form'); - var paypal_button_submit = document.querySelector('#paypal_button_submit'); - - PayPalSDK.HostedFields.render({ - styles: { - 'input': { - 'color': '#282c37', - 'transition': 'color 0.1s', - 'line-height': '3' - }, - 'input.invalid': { - 'color': '#E53A40' - }, - ':-ms-input-placeholder': { - 'color': 'rgba(0,0,0,0.6)' + var paypal_card = PayPalSDK.CardFields({ + style: { + 'input': { + 'font-size': '1rem', + 'color': '#282c37', + 'transition': 'color 0.1s', + 'padding': '0.75rem 0.75rem', + } + }, + createOrder: function() { + paypal_order_id = false; + + var card_save = ($('#paypal_card_form #paypal_card_save:checked').length ? $('#paypal_card_form #paypal_card_save:checked').val() : 0); + + $.ajax({ + method: 'post', + url: 'index.php?route=extension/payment/paypal/createOrder', + data: {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save}, + dataType: 'json', + async: false, + success: function(json) { + showPayPalAlert(json); + + paypal_order_id = json['paypal_order_id']; }, - ':-moz-placeholder': { - 'color': 'rgba(0,0,0,0.6)' + error: function(xhr, ajaxOptions, thrownError) { + console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } - }, - fields: { - number: { - selector: '#card_number', - placeholder: '#### #### #### ####' + }); + + return paypal_order_id; + }, + onApprove: function(data) { + var card_save = ($('#paypal_card_form #paypal_card_save:checked').length ? $('#paypal_card_form #paypal_card_save:checked').val() : 0); + var card_type = $('#paypal_card_form').attr('card_type'); + var card_nice_type = $('#paypal_card_form').attr('card_nice_type'); + + $.ajax({ + method: 'post', + url: 'index.php?route=extension/payment/paypal/approveOrder', + data: {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save, 'card_type': card_type, 'card_nice_type': card_nice_type, 'paypal_order_id': data.orderID}, + dataType: 'json', + async: false, + success: function(json) { + showPayPalAlert(json); + + if (json['url']) { + location = json['url']; + } }, - cvv: { - selector: '#cvv', - placeholder: '###' + error: function(xhr, ajaxOptions, thrownError) { + console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); }, - expirationDate: { - selector: '#expiration_date', - placeholder: 'MM / YYYY' + complete: function() { + $('#paypal_card_container').removeClass('paypal-spinner'); + $('#paypal_card_button').prop('disabled', false).button('reset'); } - }, - createOrder: function(data, actions) { - paypal_order_id = false; - - $.ajax({ - method: 'post', - url: 'index.php?route=extension/payment/paypal/createOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'card'}, - dataType: 'json', - async: false, - success: function(json) { - showPayPalAlert(json); - - paypal_order_id = json['paypal_order_id']; - }, - error: function(xhr, ajaxOptions, thrownError) { - console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); - } - }); - - return paypal_order_id; - } - }).then(function(hostedFieldsInstance) { - hostedFieldsInstance.on('blur', function (event) { - console.log('CCF Event "blur", state=' + hostedFieldsInstance.getState() + ', event=' + event); - }); - - hostedFieldsInstance.on('focus', function (event) { - console.log('CCF Event "focus", state=' + hostedFieldsInstance.getState() + ', event=' + event); }); + }, + inputEvents: { + onChange: function(data) { + console.log('CCF Event "change", state=' + paypal_card.getState() + ', event=' + data); + + $('#paypal_card_form').removeClass().addClass('well'); + $('#paypal_card_form').removeAttr(); + + if (data.cards.length === 1) { + $('#paypal_card_form').addClass(data.cards[0].type); + $('#paypal_card_form').attr('card_type', data.cards[0].type); + $('#paypal_card_form').attr('card_nice_type', data.cards[0].niceType); + } - hostedFieldsInstance.on('validityChange', function (event) { - console.log('CCF Event "validityChange", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - // Check if all fields are valid, then show submit button - var formValid = Object.keys(event.fields).every(function (key) { - return event.fields[key].isValid; - }); - - if (formValid) { - $('#paypal_button_submit').addClass('show-button'); + if (data.isFormValid) { + $('#paypal_card_button').addClass('show-button'); } else { - $('#paypal_button_submit').removeClass('show-button'); + $('#paypal_card_button').removeClass('show-button'); } - }); - - hostedFieldsInstance.on('notEmpty', function (event) { - console.log('CCF Event "notEmpty", state=' + hostedFieldsInstance.getState() + ', event=' + event); - }); - - hostedFieldsInstance.on('empty', function (event) { - console.log('CCF Event "empty", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - $(paypal_card_form).removeClass().addClass('well'); - $('#card_image').removeClass(); - }); - - hostedFieldsInstance.on('cardTypeChange', function (event) { - console.log('CCF Event "cardTypeChange", state=' + hostedFieldsInstance.getState() + ',event=' + event); - - $(paypal_card_form).removeClass().addClass('well'); - $('#card_image').removeClass(); - - // Change card bg depending on card type - if (event.cards.length === 1) { - $(paypal_card_form).addClass(event.cards[0].type); - $('#card_image').addClass(event.cards[0].type); - - // Change the CVV length for AmericanExpress cards - if (event.cards[0].code.size === 4) { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '####' - }); - } else { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '###' - }); - } - } else { - hostedFieldsInstance.setAttribute({ - field: 'cvv', - attribute: 'placeholder', - value: '###' - }); + }, + onFocus: function(data) { + console.log('CCF Event "focus", state=' + paypal_card.getState() + ', event=' + data); + }, + onBlur: function(data) { + console.log('CCF Event "blur", state=' + paypal_card.getState() + ', event=' + data); + }, + onInputSubmitRequest: function(data) { + console.log('CCF Event "input submit request", state=' + paypal_card.getState() + ', event=' + data); + + if (data.isFormValid) { + $('#paypal_card_button').addClass('show-button'); + } else { + $('#paypal_card_button').removeClass('show-button'); } - }); - - paypal_button_submit.addEventListener('click', function (event) { - event.preventDefault(); + } + } + }); + + if (paypal_card.isEligible()) { + paypal_card.NameField().render('#card_holder_name'); + paypal_card.NumberField().render('#card_number'); + paypal_card.ExpiryField().render('#expiration_date'); + paypal_card.CVVField().render('#cvv'); - if ($('#paypal_button_submit').hasClass('show-button')) { - console.log('CCF Event "click", state=' + hostedFieldsInstance.getState() + ',event=' + event); + var paypal_card_button = document.querySelector('#paypal_card_button'); + + paypal_card_button.addEventListener('click', function(event) { + event.preventDefault(); + + if ($('#paypal_card_button').hasClass('show-button')) { + console.log('CCF Event "click", state=' + paypal_card.getState() + ', event=' + event); - $('#paypal_card_container').addClass('paypal-spinner'); - - hostedFieldsInstance.submit({ - // Need to specify when triggering 3D Secure authentication - contingencies: (paypal_data['card_secure_status'] ? ['3D_SECURE'] : '') - - }).then(function (payload) { - console.log('PayPal CCF submitted:', payload); + $('#paypal_card_container').addClass('paypal-spinner'); + $('#paypal_card_button').prop('disabled', true).button('loading'); - $.ajax({ - method: 'post', - url: 'index.php?route=extension/payment/paypal/approveOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'card', 'payload': JSON.stringify(payload)}, - dataType: 'json', - async: false, - success: function(json) { - showPayPalAlert(json); - - if (json['url']) { - location = json['url']; - } - }, - error: function(xhr, ajaxOptions, thrownError) { - console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); - }, - complete: function() { - $('#paypal_card_container').removeClass('paypal-spinner'); - } - }); - }); - } - }, false); - }); + paypal_card.submit().then(function() { + console.log('PayPal CCF submitted:', paypal_card); + }).catch(function(error) { + console.error('PayPal CCF submit erred:', error); + }); + } + }, false); } else { console.log('Not eligible for CCF'); } @@ -450,22 +510,17 @@ var PayPalAPI = (function () { } $('#paypal_card_container').removeClass('paypal-spinner'); + $('#paypal_card_button').prop('disabled', false).button('reset'); } - if (paypal_data['components'].includes('messages') && $('#paypal_message').length && !$('#paypal_message_container').html()) { - $('#paypal_message').css('text-align', paypal_data['message_align']); - - if (paypal_data['message_width']) { - $('#paypal_message_container').css('display', 'inline-block'); - $('#paypal_message_container').css('width', paypal_data['message_width']); - } else { - $('#paypal_message_container').css('display', 'block'); - $('#paypal_message_container').css('width', 'auto'); - } - + if (paypal_data['components'].includes('messages') && $('#paypal_message').length && !$('#paypal_message_container').html()) { var paypal_message = document.createElement('div'); paypal_message.setAttribute('data-pp-message', ''); + + if (paypal_data['page_code'] == 'home') { + paypal_message.setAttribute('data-pp-placement', 'home'); + } if (paypal_data['page_code'] == 'product') { paypal_message.setAttribute('data-pp-placement', 'product'); @@ -483,6 +538,8 @@ var PayPalAPI = (function () { paypal_message.setAttribute('data-pp-style-layout', paypal_data['message_layout']); if (paypal_data['message_layout'] == 'text') { + paypal_message.setAttribute('data-pp-style-logo-type', paypal_data['message_logo_type']); + paypal_message.setAttribute('data-pp-style-logo-position', paypal_data['message_logo_position']); paypal_message.setAttribute('data-pp-style-text-color', paypal_data['message_text_color']); paypal_message.setAttribute('data-pp-style-text-size', paypal_data['message_text_size']); } else { @@ -493,6 +550,18 @@ var PayPalAPI = (function () { document.querySelector('#paypal_message_container').appendChild(paypal_message); $('#paypal_message_container').removeClass('paypal-spinner'); + + if (paypal_data['page_code'] == 'product') { + $('[name^="option"], [name="quantity"]').on('change', function(event) { + setTimeout(function() { + updatePayPalData(); + + if (paypal_message) { + paypal_message.setAttribute('data-pp-amount', paypal_data['message_amount']); + } + }, 10); + }); + } } if (paypal_callback && typeof paypal_callback == 'function') { @@ -504,16 +573,22 @@ var PayPalAPI = (function () { const {allowedPaymentMethods, merchantInfo, apiVersion, apiVersionMinor, countryCode} = await PayPalSDK.Googlepay().config(); const paymentsClient = new google.payments.api.PaymentsClient({ + environment: paypal_data['googlepay_environment'], paymentDataCallbacks: { onPaymentAuthorized: function(paymentData) { return new Promise(async function(resolve, reject) { try { paypal_order_id = false; + product_data = false; + + if (paypal_data['page_code'] == 'product') { + product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); + } $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/createOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'googlepay_button'}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'product': product_data}, dataType: 'json', async: false, success: function(json) { @@ -526,6 +601,8 @@ var PayPalAPI = (function () { } }); + paymentData.paymentMethodData.info.billingAddress.phoneNumber = paymentData.paymentMethodData.info.billingAddress.phoneNumber.replace('+', ''); + const confirmOrderResponse = await PayPalSDK.Googlepay().confirmOrder({ orderId: paypal_order_id, paymentMethodData: paymentData.paymentMethodData @@ -538,7 +615,7 @@ var PayPalAPI = (function () { $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/approveOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'googlepay_button', 'paypal_order_id': paypal_order_id}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData)}, dataType: 'json', async: false, success: function(json) { @@ -561,7 +638,7 @@ var PayPalAPI = (function () { $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/approveOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'googlepay_button', 'paypal_order_id': paypal_order_id}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData)}, dataType: 'json', async: false, success: function(json) { @@ -625,7 +702,7 @@ var PayPalAPI = (function () { $('#googlepay_button_container').removeClass('shape-pill'); $('#googlepay_button_container').addClass('shape-rect'); } - + const googlepay_button = paymentsClient.createButton({ buttonColor: paypal_data['googlepay_button_color'], buttonType: paypal_data['googlepay_button_type'], @@ -634,7 +711,10 @@ var PayPalAPI = (function () { onClick: function() { const paymentDataRequest = Object.assign({}, {apiVersion, apiVersionMinor}); + allowedPaymentMethods[0].parameters.billingAddressParameters.phoneNumberRequired = true; + paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods; + paymentDataRequest.transactionInfo = { countryCode: countryCode, currencyCode: paypal_data['currency_code'], @@ -644,9 +724,10 @@ var PayPalAPI = (function () { } paymentDataRequest.merchantInfo = merchantInfo; - paymentDataRequest.callbackIntents = ['PAYMENT_AUTHORIZATION']; - + paymentDataRequest.emailRequired = true; + paymentDataRequest.shippingAddressRequired = true; + paymentsClient.loadPaymentData(paymentDataRequest); } }); @@ -723,8 +804,8 @@ var PayPalAPI = (function () { currencyCode: paypal_data['currency_code'], merchantCapabilities, supportedNetworks, - requiredBillingContactFields: ['name', 'phone', 'email', 'postalAddress'], - requiredShippingContactFields: [], + requiredBillingContactFields: ['name', 'postalAddress'], + requiredShippingContactFields: ['name', 'postalAddress', 'phone', 'email'], total: { label: 'Total', amount: paypal_data['applepay_amount'], @@ -785,11 +866,16 @@ var PayPalAPI = (function () { console.log(JSON.stringify(event, null, 4)); paypal_order_id = false; + product_data = false; + + if (paypal_data['page_code'] == 'product') { + product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); + } $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/createOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'applepay_button'}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'product': product_data}, dataType: 'json', async: false, success: function(json) { @@ -801,6 +887,8 @@ var PayPalAPI = (function () { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); + + event.payment.shippingContact.phoneNumber = event.payment.shippingContact.phoneNumber.replace('+', ''); await ApplePaySDK.confirmOrder({ orderId: paypal_order_id, @@ -812,7 +900,7 @@ var PayPalAPI = (function () { $.ajax({ method: 'post', url: 'index.php?route=extension/payment/paypal/approveOrder', - data: {'page_code' : paypal_data['page_code'], 'payment_type' : 'applepay_button', 'paypal_order_id': paypal_order_id}, + data: {'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(event.payment)}, dataType: 'json', async: false, success: function(json) { diff --git a/upload/catalog/view/theme/default/image/paypal/card.svg b/upload/catalog/view/theme/default/image/paypal/card.svg new file mode 100644 index 000000000..f59d5f6be --- /dev/null +++ b/upload/catalog/view/theme/default/image/paypal/card.svg @@ -0,0 +1,430 @@ + +image/svg+xml \ No newline at end of file diff --git a/upload/catalog/view/theme/default/stylesheet/paypal/card.css b/upload/catalog/view/theme/default/stylesheet/paypal/card.css index 2e30a9336..0e40f1a6d 100644 --- a/upload/catalog/view/theme/default/stylesheet/paypal/card.css +++ b/upload/catalog/view/theme/default/stylesheet/paypal/card.css @@ -1,38 +1,174 @@ +#paypal_card_tokens .paypal-card-token { + position: relative; + display: table; + width: 100%; + border-collapse: separate; + margin-bottom: 1em; +} +#paypal_card_tokens .card-token-button { + position: relative; + display: table-cell; + width: 100%; + height: 60px; + padding: 0px 8px 0px 80px; + color: #282c37; + background: #FFFFFF; + font-size: 15px; + text-align: left; + vertical-align: middle; + white-space: normal; + border: 1px solid #909697; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + -webkit-appearance: none; + box-shadow: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + overflow: hidden; + z-index: 0; + outline: 0; +} +#paypal_card_tokens .card-token-delete-button { + position: relative; + display: table-cell; + width: 1%; + height: 60px; + padding: 0px 16px; + color: #282c37; + background: #FFFFFF; + font-size: 14px; + text-align: center; + vertical-align: middle; + white-space: nowrap; + border: 1px solid #909697; + border-left: none; + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-appearance: none; + box-shadow: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + overflow: hidden; + z-index: 0; + outline: 0; +} +#paypal_card_tokens .card-token-button:hover, #paypal_card_tokens .card-token-delete-button:hover { + background: #f5f5f5; +} +#paypal_card_tokens .card-token-button:active, #paypal_card_tokens .card-token-delete-button:active { + -webkit-animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); + animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); +} +#paypal_card_tokens .card-icon { + position: absolute; + display: block; + width: 61px; + height: 36px; + left: 8px; + top: 50%; + margin-top: -18px; + background-repeat: no-repeat; + background-image: url('../../image/paypal/card.svg'); + background-size: 61px 432px; + background-position-x: left; + background-position-y: 0px; + border: none; +} +#paypal_card_tokens .card-icon-american-express { + background-position-y: -36px; +} +#paypal_card_tokens .card-icon-diners-club { + background-position-y: -72px; +} +#paypal_card_tokens .card-icon-discover { + background-position-y: -108px; +} +#paypal_card_tokens .card-icon-jcb { + background-position-y: -144px; +} +#paypal_card_tokens .card-icon-mastercard { + background-position-y: -180px; +} +#paypal_card_tokens .card-icon-maestro { + background-position-y: -216px; +} +#paypal_card_tokens .card-icon-unionpay { + background-position-y: -252px; +} +#paypal_card_tokens .card-icon-visa { + background-position-y: -288px; +} +#paypal_card_tokens .card-icon-elo { + background-position-y: -324px; +} +#paypal_card_tokens .card-icon-hiper { + background-position-y: -360px; +} +#paypal_card_tokens .card-icon-hipercard { + background-position-y: -396px; +} #paypal_card_form { color: #717171; - text-align: center; + text-align: left; transition: all 600ms cubic-bezier(0.2, 1.3, 0.7, 1); -webkit-animation: cardIntro 500ms cubic-bezier(0.2, 1.3, 0.7, 1); animation: cardIntro 500ms cubic-bezier(0.2, 1.3, 0.7, 1); z-index: 1; } -#paypal_card_form.visa { - color: #fff; - background-color: #0D4AA2; -} -#paypal_card_form.master-card { - color: #fff; - background-color: #363636; - background: linear-gradient(115deg, #d82332, #d82332 50%, #f1ad3d 50%, #f1ad3d); -} -#paypal_card_form.maestro { - color: #fff; - background-color: #363636; - background: linear-gradient(115deg, #009ddd, #009ddd 50%, #ed1c2e 50%, #ed1c2e); -} #paypal_card_form.american-express { - color: #fff; + color: #FFFFFF; background-color: #007CC3; } +#paypal_card_form.diners-club { + color: #FFFFFF; + background-color: #0079BE; +} #paypal_card_form.discover { - color: #fff; + color: #FFFFFF; background-color: #ff6000; background: linear-gradient(#d14310, #f7961e); } -#paypal_card_form.unionpay, #paypal_card_form.jcb, #paypal_card_form.diners-club { - color: #fff; +#paypal_card_form.jcb { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(90deg, #005182, #005182 33%, #BE1833 33% 67%, #00933F 67%, #00933F); +} +#paypal_card_form.mastercard { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(115deg, #D82332, #D82332 50%, #F1AD3D 50%, #F1AD3D); +} +#paypal_card_form.maestro { + color: #FFFFFF; + background-color: #363636; + background: linear-gradient(115deg, #009DDD, #009DDD 50%, #ED1C2E 50%, #ED1C2E); +} +#paypal_card_form.unionpay { + color: #FFFFFF; background-color: #363636; + background: linear-gradient(100deg, #D10429, #D10429 33%, #022E64 33% 67%, #076F74 67%, #076F74); +} +#paypal_card_form.visa { + color: #FFFFFF; + background-color: #0D4AA2; +} +#paypal_card_form.elo { + color: #FFFFFF; + background-color: #000000; +} +#paypal_card_form.hiper { + color: #FFFFFF; + background-color: #F37421; } +#paypal_card_form.hipercard { + color: #FFFFFF; + background-color: #BA1319 +} +#paypal_card_form .card-info-holder-name, #paypal_card_form .card-info-number, #paypal_card_form .card-info-date-cvv { position: relative; @@ -48,65 +184,23 @@ float: right; margin-bottom: 0.5em; } +#paypal_card_form .card-info-holder-name, #paypal_card_form .card-info-number, #paypal_card_form .card-info-date, #paypal_card_form .card-info-cvv { - transition: -webkit-transform 0.3s; - transition: transform 0.3s; - transition: transform 0.3s, -webkit-transform 0.3s; -} -#paypal_card_form .card-label { - display: block; - margin-bottom: 0.5em; - text-transform: uppercase; + transition: -webkit-transform 0.3s; + transition: transform 0.3s; + transition: transform 0.3s, -webkit-transform 0.3s; } -#paypal_card_form .card-input-container { +#paypal_card_form .card-button { position: relative; - height: 2.75em; - padding: 5px 10px; - margin-bottom: 1em; - background: rgba(255, 255, 255, 0.86); - border: 1px solid #eee; - border-radius: 2px; -} -#paypal_card_form #card_image { - position: absolute; - top: 0px; - right: 2px; - width: 44px; - height: 28px; - background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/346994/card_sprite.png); - background-size: 86px 458px; - border-radius: 4px; - background-position: -100px 0; - background-repeat: no-repeat; -} -#paypal_card_form #card_image.visa { - background-position: 0 -398px; -} -#paypal_card_form #card_image.master-card { - background-position: 0 -281px; -} -#paypal_card_form #card_image.american-express { - background-position: 0 -370px; -} -#paypal_card_form #card_image.discover { - background-position: 0 -163px; + padding: 0rem 0.6rem; } -#paypal_card_form #card_image.maestro { - background-position: 0 -251px; -} -#paypal_card_form #card_image.jcb { - background-position: 0 -221px; -} -#paypal_card_form #card_image.diners-club { - background-position: 0 -133px; -} -#paypal_card_form #paypal_button_submit { +#paypal_card_form .paypal-card-button { width: 100%; - padding: 1em 1em; - color: #fff; - background: #282c37; + padding: 16px 16px; + color: #FFFFFF; + background: #282C37; font-size: 15px; box-shadow: none; -moz-box-shadow: none; @@ -117,14 +211,21 @@ outline: 0; -webkit-appearance: none; } -#paypal_card_form #paypal_button_submit:hover { +#paypal_card_form .paypal-card-button:hover { background: #535b72; } -#paypal_card_form #paypal_button_submit:active { +#paypal_card_form.elo .paypal-card-button { + color: #000000; + background: #FFFFFF; +} +#paypal_card_form.elo .paypal-card-button:hover { + background: #F5F5F5; +} +#paypal_card_form .paypal-card-button:active { -webkit-animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); animation: cardIntro 200ms cubic-bezier(0.2, 1.3, 0.7, 1); } -#paypal_card_form #paypal_button_submit.show-button { +#paypal_card_form .paypal-card-button.show-button { opacity: 1; cursor: pointer; } \ No newline at end of file diff --git a/upload/catalog/view/theme/default/stylesheet/paypal/paypal.css b/upload/catalog/view/theme/default/stylesheet/paypal/paypal.css index 143c7590d..fcfc38fa7 100644 --- a/upload/catalog/view/theme/default/stylesheet/paypal/paypal.css +++ b/upload/catalog/view/theme/default/stylesheet/paypal/paypal.css @@ -1,5 +1,7 @@ .paypal-button { position: relative; + width: 100%; + margin: 1em 0; } @media (max-width: 476px) { .paypal-button-container { @@ -8,6 +10,8 @@ } .googlepay-button { position: relative; + width: 100%; + margin: 1em 0; } @media (max-width: 476px) { .googlepay-button-container { @@ -25,6 +29,8 @@ } .applepay-button { position: relative; + width: 100%; + margin: 1em 0; } @media (max-width: 476px) { .applepay-button-container { @@ -34,6 +40,17 @@ width: 100% !important; } } +.paypal-card-tokens { + position: relative; +} +.paypal-card-tokens-container { + position: relative; +} +@media (max-width: 476px) { + .paypal-card-tokens-container { + width: 100% !important; + } +} .paypal-card { position: relative; } @@ -47,6 +64,10 @@ } .paypal-message { position: relative; + margin-bottom: 10px; +} +.paypal-message [data-pp-message] > * { + max-width: none !important; } .paypal-spinner { position: relative; diff --git a/upload/catalog/view/theme/default/template/extension/payment/paypal/confirm.twig b/upload/catalog/view/theme/default/template/extension/payment/paypal/confirm.twig index 0725fc398..4d3796c70 100644 --- a/upload/catalog/view/theme/default/template/extension/payment/paypal/confirm.twig +++ b/upload/catalog/view/theme/default/template/extension/payment/paypal/confirm.twig @@ -1,714 +1,600 @@ {{ header }}
- - {% if attention %} -
{{ attention }} - -
- {% endif %} - {% if success %} + + {% if attention %} +
{{ attention }} + +
+ {% endif %} + {% if success %}
{{ success }} - +
- {% endif %} - {% if error_warning %} + {% endif %} + {% if error_warning %}
{{ error_warning }} - -
- {% endif %} -
- {{ column_left }} - {% if column_left and column_right %} - {% set class = 'col-sm-6' %} - {% elseif column_left or column_right %} - {% set class = 'col-sm-9' %} - {% else %} - {% set class = 'col-sm-12' %} - {% endif %} -
- {{ content_top }} -

{{ heading_title }}

-
-
-

- {{ text_checkout_payment_address }} -
-

-
-
-
-
-
- {{ text_your_details }} - - {% if guest.firstname %} - - - - - {% endif %} - {% if guest.lastname %} - - - - - {% endif %} - {% if guest.email %} - - - - - {% endif %} - {% if guest.telephone %} - - - - - {% endif %} - {% for custom_field in custom_fields %} - {% if custom_field.location == 'account' %} - - - - - {% endif %} - {% endfor %} -
{{ entry_firstname }}{{ guest.firstname }}
{{ entry_lastname }}{{ guest.lastname }}
{{ entry_email }}{{ guest.email }}
{{ entry_telephone }}{{ guest.telephone }}
{{ custom_field.name }}{{ custom_field.value }}
-
-
-
-
- {{ text_your_address }} - - {% if payment_address.company %} - - - - - {% endif %} - {% if payment_address.address_1 %} - - - - - {% endif %} - {% if payment_address.address_2 %} - - - - - {% endif %} - {% if payment_address.city %} - - - - - {% endif %} - {% if payment_address.postcode %} - - - - - {% endif %} - {% if payment_address.country %} - - - - - {% endif %} - {% if payment_address.zone %} - - - - - {% endif %} - {% for custom_field in custom_fields %} - {% if custom_field.location == 'address' %} - - - - - {% endif %} - {% endfor %} -
{{ entry_company }}{{ payment_address.company }}
{{ entry_address_1 }}{{ payment_address.address_1 }}
{{ entry_address_2 }}{{ payment_address.address_2 }}
{{ entry_city }}{{ payment_address.city }}
{{ entry_postcode }}{{ payment_address.postcode }}
{{ entry_country }}{{ payment_address.country }}
{{ entry_zone }}{{ payment_address.zone }}
{{ custom_field.name }}{{ custom_field.value }}
-
-
-
-
-
- {% if has_shipping %} -
-
-

- {{ text_checkout_shipping_address }} -
-

-
-
- - {% if shipping_address.firstname %} - - - - - {% endif %} - {% if shipping_address.lastname %} - - - - - {% endif %} - {% if shipping_address.company %} - - - - - {% endif %} - {% if shipping_address.address_1 %} - - - - - {% endif %} - {% if shipping_address.address_2 %} - - - - - {% endif %} - {% if shipping_address.city %} - - - - - {% endif %} - {% if shipping_address.postcode %} - - - - - {% endif %} - {% if shipping_address.country %} - - - - - {% endif %} - {% if shipping_address.zone %} - - - - - {% endif %} - {% for custom_field in custom_fields %} - {% if custom_field.location == 'address' %} - - - - - {% endif %} - {% endfor %} -
{{ entry_firstname }}{{ shipping_address.firstname }}
{{ entry_lastname }}{{ shipping_address.lastname }}
{{ entry_company }}{{ shipping_address.company }}
{{ entry_address_1 }}{{ shipping_address.address_1 }}
{{ entry_address_2 }}{{ shipping_address.address_2 }}
{{ entry_city }}{{ shipping_address.city }}
{{ entry_postcode }}{{ shipping_address.postcode }}
{{ entry_country }}{{ shipping_address.country }}
{{ entry_zone }}{{ shipping_address.zone }}
{{ custom_field.name }}{{ custom_field.value }}
-
-
- {% endif %} - {% if has_shipping %} - {% if not shipping_methods %} -
{{ error_no_shipping }}
- {% else %} -
-
-
-

{{ text_checkout_shipping_method }}

-
-
- {% for shipping_method in shipping_methods %} -

{{ shipping_method.title }}

- {% if not shipping_method.error %} - {% for quote in shipping_method.quote %} -
- -
- {% endfor %} - {% else %} -
{{ shipping_method.error }}
- {% endif %} - {% endfor %} -
-
-
- {% endif %} - {% endif %} -
-
-

{{ text_checkout_payment_method }}

-
-
- {% for payment_method in payment_methods %} - {% if payment_method.code == 'paypal' %} -
- -
- {% endif %} - {% endfor %} -
-
-
- - - - - - - - - - - - {% for product in products %} - - - - - - - - {% endfor %} - {% for voucher in vouchers %} - - - - - - - - {% endfor %} - -
{{ column_name }}{{ column_model }}{{ column_quantity }}{{ column_price }}{{ column_total }}
- {{ product.name }} - {% for option in product.option %}
- - {{ option.name }}: {{ option.value }} - {% endfor %} - {% if product.subscription %} -
{{ text_recurring_item }} {{ product.subscription }} - {% endif %}
{{ product.model }}{{ product.quantity }}{{ product.price }}{{ product.total }}
{{ voucher.description }}1{{ voucher.amount }}{{ voucher.amount }}
-
-
- {% if total_coupon or total_voucher or total_reward %} -
{{ total_coupon }}{{ total_voucher }}{{ total_reward }}
-
- {% endif %} -
-
- - {% for total in totals %} - - - - - {% endfor %} -
{{ total.title }}:{{ total.text }}
-
-
- - {{ content_bottom }} +
- {{ column_right }} -
+ {% endif %} +
{{ column_left }} + {% if column_left and column_right %} + {% set class = 'col-sm-6' %} + {% elseif column_left or column_right %} + {% set class = 'col-sm-9' %} + {% else %} + {% set class = 'col-sm-12' %} + {% endif %} +
{{ content_top }} +

{{ heading_title }}

+
+
+

{{ text_checkout_payment_address }}

+
+
+
+
+
+ {{ text_your_details }} + + {% if guest['firstname'] %}{% endif %} + {% if guest['lastname'] %}{% endif %} + {% if guest['email'] %}{% endif %} + {% if guest['telephone'] %}{% endif %} + {% for custom_field in custom_fields %} + {% if custom_field['location'] == 'account' %} + + {% endif %} + {% endfor %} +
{{ entry_firstname }}{{ guest['firstname'] }}
{{ entry_lastname }}{{ guest['lastname'] }}
{{ entry_email }}{{ guest['email'] }}
{{ entry_telephone }}{{ guest['telephone'] }}
{{ custom_field['name'] }}{{ custom_field['value'] }}
+
+
+
+
+ {{ text_your_address }} + + {% if payment_address['company'] %}{% endif %} + {% if payment_address['address_1'] %}{% endif %} + {% if payment_address['address_2'] %}{% endif %} + {% if payment_address['city'] %}{% endif %} + {% if payment_address['postcode'] %}{% endif %} + {% if payment_address['country'] %}{% endif %} + {% if payment_address['zone'] %}{% endif %} + {% for custom_field in custom_fields %} + {% if custom_field['location'] == 'address' %} + + {% endif %} + {% endfor %} +
{{ entry_company }}{{ payment_address['company'] }}
{{ entry_address_1 }}{{ payment_address['address_1'] }}
{{ entry_address_2 }}{{ payment_address['address_2'] }}
{{ entry_city }}{{ payment_address['city'] }}
{{ entry_postcode }}{{ payment_address['postcode'] }}
{{ entry_country }}{{ payment_address['country'] }}
{{ entry_zone }}{{ payment_address['zone'] }}
{{ custom_field['name'] }}{{ custom_field['value'] }}
+
+
+
+
+
+ {% if has_shipping %} +
+
+

{{ text_checkout_shipping_address }}

+
+
+ + {% if shipping_address['firstname'] %}{% endif %} + {% if shipping_address['lastname'] %}{% endif %} + {% if shipping_address['company'] %}{% endif %} + {% if shipping_address['address_1'] %}{% endif %} + {% if shipping_address['address_2'] %}{% endif %} + {% if shipping_address['city'] %}{% endif %} + {% if shipping_address['postcode'] %}{% endif %} + {% if shipping_address['country'] %}{% endif %} + {% if shipping_address['zone'] %}{% endif %} + {% for custom_field in custom_fields %} + {% if custom_field['location'] == 'address' %} + + {% endif %} + {% endfor %} +
{{ entry_firstname }}{{ shipping_address['firstname'] }}
{{ entry_lastname }}{{ shipping_address['lastname'] }}
{{ entry_company }}{{ shipping_address['company'] }}
{{ entry_address_1 }}{{ shipping_address['address_1'] }}
{{ entry_address_2 }}{{ shipping_address['address_2'] }}
{{ entry_city }}{{ shipping_address['city'] }}
{{ entry_postcode }}{{ shipping_address['postcode'] }}
{{ entry_country }}{{ shipping_address['country'] }}
{{ entry_zone }}{{ shipping_address['zone'] }}
{{ custom_field['name'] }}{{ custom_field['value'] }}
+
+
+ {% endif %} + {% if has_shipping %} + {% if not shipping_methods %} +
{{ error_no_shipping }}
+ {% else %} +
+
+
+

{{ text_checkout_shipping_method }}

+
+
+ {% for shipping_method in shipping_methods %} +

{{ shipping_method['title'] }}

+ {% if not shipping_method['error'] %} + {% for quote in shipping_method['quote'] %} +
+ +
+ {% endfor %} + {% else %} +
{{ shipping_method['error'] }}
+ {% endif %} + {% endfor %} +
+
+
+ {% endif %} + {% endif %} +
+
+

{{ text_checkout_payment_method }}

+
+
+ {% for payment_method in payment_methods %} + {% if payment_method['code'] == payment_method_code %} +
+ +
+ {% endif %} + {% endfor %} +
+
+
+ + + + + + + + + + + + {% for product in products %} + + + + + + + + {% endfor %} + {% for voucher in vouchers %} + + + + + + + + {% endfor %} + +
{{ column_name }}{{ column_model }}{{ column_quantity }}{{ column_price }}{{ column_total }}
+ {{ product['name'] }} + {% for option in product['option'] %}
+ - {{ option['name'] }}: {{ option['value'] }} + {% endfor %} + {% if product['recurring'] %} +
{{ text_recurring_item }} {{ product['recurring'] }} + {% endif %} +
{{ product['model'] }}{{ product['quantity'] }}{{ product['price'] }}{{ product['total'] }}
{{ voucher['description'] }}1{{ voucher['amount'] }}{{ voucher['amount'] }}
+
+
+ {% if total_coupon or total_voucher or total_reward %} +
{{ total_coupon }}{{ total_voucher }}{{ total_reward }}

+ {% endif %} +
+
+ + {% for total in totals %} + + + + + {% endfor %} +
{{ total['title'] }}:{{ total['text'] }}
+
+
+ + {{ content_bottom }} +
+ {{ column_right }} +
{{ footer }} \ No newline at end of file diff --git a/upload/catalog/view/theme/default/template/extension/payment/paypal/failure.twig b/upload/catalog/view/theme/default/template/extension/payment/paypal/failure.twig new file mode 100644 index 000000000..3ca933af6 --- /dev/null +++ b/upload/catalog/view/theme/default/template/extension/payment/paypal/failure.twig @@ -0,0 +1,27 @@ +{{ header }} +
+ +
{{ column_left }} + {% if column_left and column_right %} + {% set class = 'col-sm-6' %} + {% elseif column_left or column_right %} + {% set class = 'col-sm-9' %} + {% else %} + {% set class = 'col-sm-12' %} + {% endif %} +
{{ content_top }} +

{{ text_title }}

+ {{ text_message }} + + {{ content_bottom }} +
+ {{ column_right }} +
+
+{{ footer }} \ No newline at end of file diff --git a/upload/catalog/view/theme/default/template/extension/payment/paypal/message.twig b/upload/catalog/view/theme/default/template/extension/payment/paypal/message.twig index cce613083..78f174729 100644 --- a/upload/catalog/view/theme/default/template/extension/payment/paypal/message.twig +++ b/upload/catalog/view/theme/default/template/extension/payment/paypal/message.twig @@ -1,9 +1,8 @@ -
-
-
-
+
\ No newline at end of file diff --git a/upload/catalog/view/theme/default/template/extension/payment/paypal/payment_address.twig b/upload/catalog/view/theme/default/template/extension/payment/paypal/payment_address.twig index f739db197..8909b2063 100644 --- a/upload/catalog/view/theme/default/template/extension/payment/paypal/payment_address.twig +++ b/upload/catalog/view/theme/default/template/extension/payment/paypal/payment_address.twig @@ -1,272 +1,312 @@ -