diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1df548e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,66 @@
+# NOVALNET PAYMENT INTEGRATION FOR OPENCART
+Novalnet’s Payment Module for opencart ensures simple and secure integration of payments and payment services for opencart shops, allowing shop owners to automate the entire payment process from checkout till collection.
+
+## Requirements
+Novalnet merchant account is required for using this Novalnet Payment Gateway for opencart. The module is available for the 3.0.0.0 - 3.0.3.9 versions in the following languages: EN & DE.
+
+## Advanced functions for payment processing
+- Easy configuration of international and local payment methods
+- One PCI DSS certified payment platform for all payment services
+- Credit Card iframe integration with custom CSS configuration
+- Comprehensive fraud management solution with more than 60 supported modules
+- Secure SSL-encoded gateways
+- Proxy server configuration
+- Updating transaction amounts for Direct Debit SEPA, Invoice, Prepayment & Barzahlen/viacash
+- Changing due dates for Prepayment & Invoice payment
+- Automatic order creation when subscriptions are renewed
+- One-click shopping supported
+- Easy confirmation & cancellation of on-hold transactions
+- Refund options for various payment types
+- Setting a time limit for orders & automatic order cancellation when limit is exceeded
+- Cancelling subscriptions in the shops’ frontend and admin side
+- Responsive templates
+
+For detailed documentation and other technical inquiries, please send us an email to technic@novalnet.de.
+
+## Integrated payment methods
+- Direct Debit SEPA
+- Credit/Debit Cards
+- Invoice
+- Prepayment
+- Barzahlen/viacash
+- Sofort
+- PayPal
+- iDEAL
+- eps
+- giropay
+- Przelewy24
+- Direct Debit SEPA with payment guarantee
+- Invoice with payment guarantee
+
+## Installation
+Easy installation of Novalnet Payment Module for opencart will be done through the following steps:
+1. Get the payment module & detailed documentation by contacting us
+2. Install the module to your OpenCart shop
+3. Configure Product Activation Key in the shop admin panel
+4. Activate & configure the preferred payment types in your shop admin panel
+
+## License
+See our License Agreement at: https://www.novalnet.com/payment-plugins/free/license
+
+## Documentation & Support
+For more information about the Opencart Novalnet Payment module and pricing for opencart, please get in touch with us: sales@novalnet.de or +49 89 9230683-20
+
+Novalnet AG
+Zahlungsinstitut (ZAG)
+Gutenbergstraße 7
+D-85748 Garching
+Deutschland
+E-mail: sales@novalnet.de
+Tel: +49 89 9230683-20
+Web: www.novalnet.de
+
+## Who is Novalnet AG?
+
The experienced and international team of specialists at Novalnet is committed to support online merchants with in-depth knowledge to increase revenue and ensure secure online payments.
diff --git a/admin/controller/extension/payment/novalnet.php b/admin/controller/extension/payment/novalnet.php
new file mode 100644
index 0000000..eb56114
--- /dev/null
+++ b/admin/controller/extension/payment/novalnet.php
@@ -0,0 +1,801 @@
+ '',
+ 'error_warning_id' => '',
+ );
+
+ private $json = array();
+
+ public function index() {
+
+ // Load language.
+ $this->load->language('extension/payment/novalnet');
+
+ $this->document->setTitle($this->language->get('novalnet_heading_title'));
+
+ // Load novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Store payment configuration.
+ if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
+ $this->model_extension_payment_novalnet->storeConfigurations('payment_novalnet');
+ }
+
+ // Get template details.
+ $data = $this->model_extension_payment_novalnet->getTemplateDetails('novalnet');
+
+ // Assign title.
+ $data['novalnet_heading_title'] = $this->language->get('novalnet_heading_title');
+
+ // Assign default values.
+ $data['server_ip'] = $this->getIpAddress('SERVER_ADDR');
+ $data['remote_ip'] = $this->getIpAddress('REMOTE_ADDR');
+ $data['default_callback_url'] = (($this->request->server['HTTPS']) ? HTTPS_CATALOG : HTTP_CATALOG) . 'index.php?route=callback/vendorScript';
+ $data['cron_job_url'] = (($this->request->server['HTTPS']) ? HTTPS_CATALOG : HTTP_CATALOG) . 'index.php?route=extension/recurring/novalnet_recurring/cronProcess';
+ // Assign error.
+ $data['error_warning'] = $this->error['error_warning'];
+ $data['error_warning_id'] = $this->error['error_warning_id'];
+
+ // Add language content.
+ $this->getLanguageContent($data);
+
+ // Add configuration content.
+ $this->getConfigurationContent($data);
+
+ $this->model_extension_payment_novalnet->install();
+
+ // Add template.
+ $this->response->setOutput($this->load->view('extension/payment/novalnet', $data));
+ }
+
+ public function install() {
+ $this->load->model('extension/payment/novalnet');
+ $this->load->model('setting/event');
+ $this->model_setting_event->addEvent('novalnet_login', 'catalog/controller/account/logout/after', 'extension/module/novalnet/logout');
+ }
+
+ public function uninstall() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEvent('novalnet_login');
+ }
+
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent(&$data) {
+ foreach (array(
+ 'entry_merchant_id',
+ 'entry_authcode',
+ 'entry_project_id',
+ 'entry_tariff',
+ 'entry_tariff_desc',
+ 'heading_title',
+ 'entry_payment_access_key',
+ 'entry_onhold_limit',
+ 'entry_referrer_id',
+ 'entry_payment_logo',
+ 'entry_proxy_server',
+ 'entry_gateway_timeout',
+ 'entry_onhold_management',
+ 'entry_onhold_confirm_status',
+ 'entry_onhold_cancel_status',
+ 'entry_merchant_script_management',
+ 'entry_merchant_script_test_mode',
+ 'entry_merchant_script_test_mode_desc',
+ 'entry_merchant_script_mail_notification',
+ 'entry_merchant_script_mail_notification_desc',
+ 'entry_notification_url',
+ 'entry_email_to_addr',
+ 'entry_email_bcc_addr',
+ 'novalnet_payment_logo',
+ 'text_true',
+ 'text_false',
+ 'entry_status',
+ 'entry_enable_payment',
+ 'text_enabled',
+ 'text_disabled',
+ 'entry_product_activation_key',
+ 'entry_client_key',
+ 'entry_subscription_tariff_id',
+ 'entry_enable_subscription',
+ 'entry_product_activation_key_desc',
+ 'error_mandatory_fields',
+ 'text_novalnet',
+ 'entry_admin_portal_src',
+ 'entry_paypal_admin_portal_src',
+ 'entry_product_activation_key_desc',
+ 'entry_vendor_desc',
+ 'entry_authcode_desc',
+ 'entry_product_desc',
+ 'entry_payment_access_key_desc',
+ 'entry_onhold_limit_desc',
+ 'entry_referrer_id_desc',
+ 'entry_proxy_server_desc',
+ 'entry_gateway_timeout_desc',
+ 'entry_payment_logo_desc',
+ 'entry_subs_tariff_desc',
+ 'entry_subs_amount_desc',
+ 'entry_subs_period_desc',
+ 'entry_email_to_addr_desc',
+ 'entry_email_bcc_addr_desc',
+ 'entry_notification_url_desc',
+ 'entry_cron_job_url',
+ 'entry_cron_job_url_desc',
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ }
+
+ /**
+ * Get configuration content.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getConfigurationContent(&$data) {
+ foreach (array(
+ 'payment_novalnet_merchant_id',
+ 'payment_novalnet_authcode',
+ 'payment_novalnet_project_id',
+ 'payment_novalnet_tariff_id',
+ 'payment_novalnet_access_key',
+ 'payment_novalnet_manual_limit',
+ 'payment_novalnet_onhold_complete_status',
+ 'payment_novalnet_cancel_status',
+ 'payment_novalnet_callback_testmode',
+ 'payment_novalnet_callback_to_addr',
+ 'payment_novalnet_callback_mail',
+ 'payment_novalnet_notification_url',
+ 'payment_novalnet_payment_logo',
+ 'payment_novalnet_public_key',
+ 'payment_novalnet_client_key',
+ 'payment_novalnet_cron_job_url',
+ 'payment_novalnet_email_notification'
+ ) as $field) {
+ $data[$field] = (isset($this->request->post[$field])) ? $this->request->post[$field] : $this->config->get($field);
+ }
+
+ }
+
+ protected function validate() {
+ if (!function_exists('crc32') || !function_exists('bin2hex') || !function_exists('base64_encode') || !function_exists('base64_decode') || !function_exists('pack')) {
+ $this->error['error_warning'] = $this->language->get('package_error');
+ return false;
+ } else if (empty($this->request->post['payment_novalnet_public_key'])) {
+ $this->error['error_warning'] = $this->language->get('error_mandatory_fields');
+ $this->error['error_warning_id'] = 'payment_novalnet_public_key';
+ return false;
+ } else if (empty($this->request->post['payment_novalnet_client_key'])) {
+ $this->error['error_warning'] = $this->language->get('error_mandatory_fields');
+ $this->error['error_warning_id'] = 'payment_novalnet_client_key';
+ return false;
+ } else if (empty($this->request->post['payment_novalnet_tariff_id'])) {
+ $this->error['error_warning'] = $this->language->get('error_mandatory_fields');
+ $this->error['error_warning_id'] = 'novalnet_tariff_id';
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * For send the request parameters to the server and manage the Novalnet orders(capture / cancel)
+ *
+ * @param $order_details
+ * @return array
+ */
+ public function novalnetApiProcess($order_details) {
+ $this->load->model('extension/payment/novalnet');
+ $api_params = array(
+ 'vendor' => $order_details['payment_configurations']['vendor'],
+ 'auth_code' => $order_details['payment_configurations']['auth_code'],
+ 'product' => $order_details['payment_configurations']['product'],
+ 'tariff' => $order_details['payment_configurations']['tariff'],
+ 'key' => $order_details['payment_id'],
+ 'tid' => $order_details['tid'],
+ 'status' => '100',
+ 'remote_ip' => $this->getIpAddress('REMOTE_ADDR'),
+ );
+
+ switch ($this->request->post['novalnet_action']) {
+ case 'capture_void_process':
+ $api_params['edit_status'] = '1';
+
+ // Add requested status.
+ $api_params['status'] = $this->request->post['transaction_status'];
+ break;
+ case 'refund_process':
+ $api_params['refund_request'] = '1';
+
+ // Add refund amount in request.
+ $api_params['refund_param'] = trim($this->request->post['transaction_refund_amount']);
+
+ // Add refund reference.
+ if(!empty($this->request->post['refund_ref'])) {
+ $api_params['refund_ref'] = trim($this->request->post['refund_ref']);
+ }
+ break;
+ case 'amount_booking_process':
+ unset($order_details['zero_amount_details']['create_payment_ref']);
+ $api_params = $order_details['zero_amount_details'];
+
+ // Add booking amount in request.
+ $api_params['amount'] = trim($this->request->post['booking_amount']);
+ $api_params['payment_ref'] = $order_details['tid'];
+ $api_params['order_no'] = $this->request->post['order_no'];
+ break;
+ case 'amount_update_process':
+ $api_params['edit_status'] = '1';
+ $api_params['update_inv_amount'] = '1';
+
+ // Add updated amount in request.
+ $api_params['amount'] = trim($this->request->post['novalnetAmountUpdate']);
+
+ // Check for due date update.
+ if ($order_details['payment_id'] == '27' ) {
+ $api_params['due_date'] = trim($this->request->post['dueDateUpdate']);
+ }
+ elseif ($order_details['payment_id'] == '59' ) {
+ $api_params['due_date'] = trim($this->request->post['expiryDateUpdate']);
+ }
+ break;
+ }
+
+ $response = $this->performCurlProcess('https://payport.novalnet.de/paygate.jsp', $api_params);
+
+ parse_str($response, $api_response);
+ return $api_response;
+ }
+
+ /**
+ * Perform CURL process
+ *
+ * @param $url
+ * @param $form
+ * @return string
+ */
+ public function performCurlProcess($url, $form) {
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $form);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $data = curl_exec($ch);
+ curl_close($ch);
+ return $data;
+ }
+
+ /**
+ * Get order status
+ *
+ * @param none
+ * @return integer
+ */
+ public function getOrderStatus() {
+ $result = $this->model_extension_payment_novalnet->dbSelect('order', 'order_status_id', 'order_id =' . $this->request->post['order_no']);
+ return $result['order_status_id'];
+ }
+
+ /**
+ * Confirm or Cancel process for the particular transactions.
+ *
+ * @param none
+ * @return boolean
+ */
+ public function captureVoid() {
+ $this->load->language('extension/payment/novalnet_common');
+ $this->load->model('extension/payment/novalnet');
+
+ // Validate status.
+ if (empty($this->request->post['transaction_status'])) {
+ $this->json['novalnet_field_error'] = $this->language->get('select_errors');
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ } else {
+
+ $order_details = $this->model_extension_payment_novalnet->getNovalnetOrders($this->request->request['order_id']);
+
+ // Perform Novalnet API process.
+ $response = $this->novalnetApiProcess($order_details);
+ // Check for valid response.
+ if ($this->checkResponseStatus($response)) {
+ $status = '';
+ // Check for capture process.
+ if(isset($order_details['payment_id']) && in_array($order_details['payment_id'], array('27', '41','40','37','6','34'))) {
+ if($response['tid_status'] == 100 || ($response['tid_status'] == 90 && $order_details['payment_id'] == '34')) {
+ if(in_array($order_details['payment_id'], array('27', '41')))
+ {
+ $this->json['success'] = $order_details['novalnet_comments'] = sprintf($this->language->get('text_invoice_transaction_confirm'), $order_details['tid'], ($response['due_date']));
+ }
+ else{
+ $this->json['success'] = $order_details['novalnet_comments'] = sprintf($this->language->get('text_transaction_confirm'), date('Y-m-d'), date('H:i:s'));
+ }
+
+ $status = ($order_details['payment_id'] == '41') ? $this->config->get('payment_' . $order_details['payment_type'] . '_callback_order_status') : $this->config->get('payment_' . $order_details['payment_type'] . '_order_completion_status');
+ $qry = $this->db->query('SELECT additional_details FROM ' . DB_PREFIX . 'novalnet_transactions WHERE tid = '.$order_details['tid']);
+ $bank_details = (array)json_decode($qry->row['additional_details']);
+ $bank_details['tid'] = $order_details['tid'];
+ $bank_details['invoice_account_holder'] = 'Novalnet AG';
+ $invoice_details = array(
+ 'amount' => $order_details['transaction_details']['amount'] / 100,
+ 'currency' => $order_details['transaction_details']['currency'],
+ );
+ $novalnet_invoice_comments = $this->prepareNovalnetComments($bank_details, $invoice_details, $order_details['payment_type'], $this->request->request['order_id'],$order_details['payment_id']);
+ $this->sendPaymentNotificationMail($this->request->request['order_id'], $novalnet_invoice_comments);
+ //Insert details into order_history table
+ $this->model_extension_payment_novalnet->updateTransactionComments($novalnet_invoice_comments, $this->request->post['transaction_status'], $status);
+ }
+
+ } elseif ($this->checkResponseStatus($response, 'tid_status')) {
+ $this->json['success'] = $order_details['novalnet_comments'] = sprintf($this->language->get('text_transaction_confirm'), date('Y-m-d'), date('H:i:s'));
+ $status = $this->config->get('payment_' . $order_details['payment_type'] . '_order_completion_status');
+ }
+
+ // Check for void process.
+ if ($this->checkResponseStatus($response, 'tid_status', '103')) {
+ $status = $this->config->get('payment_novalnet_cancel_status');
+ $this->json['success'] = $order_details['novalnet_comments'] = sprintf($this->language->get('text_transaction_cancel'), date('Y-m-d'), date('H:i:s'));
+ }
+
+ // Check for PayPal transaction ID
+ if(!empty($response['paypal_transaction_id'])) {
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_transactions', array(
+ 'additional_details' => "'" . addslashes(json_encode(array(
+ 'paypal_transaction_id' => $response['paypal_transaction_id'],
+ 'tid' => $order_details['tid'],
+ ))) . "'"
+ ), 'tid=' . $order_details['tid']);
+ }
+
+ // Update order details in tables.
+ $this->model_extension_payment_novalnet->orderDetailsUpdate($order_details, $this->request->post['transaction_status'], $status);
+ } else {
+ $this->json['error'] = $order_details['novalnet_comments'] = $this->getResponseText($response);
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ }
+ }
+
+ /**
+ * Get server response text
+ *
+ * @param $response
+ * @return string
+ */
+ public function getResponseText($response)
+ {
+ return ((!empty($response['status_desc'])) ? $response['status_desc'] : ((!empty($response['status_message'])) ? ($response['status_message']) : ((!empty($response['status_text'])) ? $response['status_text'] : $this->language->get('error_payment_not_successful'))));
+ }
+
+ /**
+ * Refund process for the particular transaction
+ *
+ * @param none
+ * @return boolean
+ */
+ public function amountRefund() {
+
+ // Load language content.
+ $this->load->language('extension/payment/novalnet_common');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Get refund amount.
+ $transaction_refund_amount = trim($this->request->post['transaction_refund_amount']);
+
+ // Validate refund amount.
+ if (!$this->validateAmount($transaction_refund_amount)) {
+ $this->json['error'] = $this->language->get('error_amount_invalid');
+
+ } else {
+
+ // Get order details.
+ $order_details = $this->model_extension_payment_novalnet->getNovalnetOrders($this->request->request['order_id']);
+
+ // Perform Novalnet API process.
+ $response = $this->novalnetApiProcess($order_details);
+
+ // Check for valid response.
+ if ($this->checkResponseStatus($response)) {
+
+ // Form notification message.
+ $order_details['novalnet_comments'] = $this->language->get('refund_parent_tid_msg1') . $order_details['tid'] . sprintf($this->language->get('refund_parent_tid_msg2'), ($this->currency->format($transaction_refund_amount / 100, $order_details['transaction_details']['currency'], '1')));
+
+ // Calculate total refunded amount.
+ $order_details['transaction_details']['refund_amount'] = ($order_details['transaction_details']['refund_amount'] + $transaction_refund_amount);
+
+ // Get Order status.
+ $order_status = ($response['tid_status'] != '100') ? $this->config->get('payment_novalnet_cancel_status') : $this->getOrderStatus();
+
+ // Add Additional note.
+ $order_details['novalnet_comments'] .= (!empty($response['tid'])) ? $this->language->get('refund_child_tid_msg') . $response['tid'] : '';
+
+ // Update order details in Novalnet tables and shop tables
+ $this->model_extension_payment_novalnet->orderDetailsUpdate($order_details, $response['tid_status'], $order_status);
+
+ // Show success message.
+ $this->json['success'] = $order_details['novalnet_comments'];
+ } else {
+ // Show error message.
+ $this->json['error'] = $this->getResponseText($response);
+ }
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ }
+
+ /**
+ * Amount update process for the particular transaction
+ *
+ * @param none
+ * @return boolean
+ */
+ public function amountUpdate() {
+ $this->load->language('extension/payment/novalnet_common');
+ $this->load->model('extension/payment/novalnet');
+
+ $updated_amount = trim($this->request->post['novalnetAmountUpdate']);
+
+ // Validate updated amount.
+ if (!$this->validateAmount($updated_amount)) {
+ $this->json['error'] = $this->language->get('error_amount_invalid');
+ } else {
+
+ // Get order details.
+ $order_details = $this->model_extension_payment_novalnet->getNovalnetOrders($this->request->request['order_id']);
+
+ // Perform Novalnet API process.
+ $response = $this->novalnetApiProcess($order_details);
+
+ // Check for valid response.
+ if ($this->checkResponseStatus($response)) {
+ $this->load->language('extension/payment/' . $order_details['payment_type']);
+
+ $due_date = '';
+
+ if($order_details['payment_id'] == '27') {
+ $due_date = !empty($this->request->post['dueDateUpdate']) ? date($this->language->get('date_format_short'), strtotime($this->request->post['dueDateUpdate'])) : '';
+ }
+ elseif ($order_details['payment_id'] == '59') {
+ $due_date = !empty($this->request->post['expiryDateUpdate']) ? date($this->language->get('date_format_short'), strtotime($this->request->post['expiryDateUpdate'])) : '';
+ }
+ // Form comments.
+ if($order_details['payment_id'] != '37') {
+ if($order_details['payment_id'] == '59' || $order_details['payment_id'] == '27') {
+ $message = ($order_details['payment_id'] == '27') ? $order_details['novalnet_comments'] = $this->language->get('message_amount_update1') . sprintf("%.2f", $updated_amount / 100) . ' ' . $order_details['transaction_details']['currency'].' ' . sprintf($this->language->get('message_amount_update2'), $due_date) : $order_details['novalnet_comments'] = $this->language->get('message_amount_update1') . sprintf("%.2f", $updated_amount / 100) . ' ' . $order_details['transaction_details']['currency'].' ' . sprintf($this->language->get('message_amount_update3'), $due_date);
+ }
+ else {
+ $message = $order_details['novalnet_comments'] = $this->language->get('message_amount_update1') . sprintf("%.2f", $updated_amount / 100) . ' ' . $order_details['transaction_details']['currency'];
+ }
+ }
+ else {
+ $message = $order_details['novalnet_comments'] = $this->language->get('sepa_amount_update1') . sprintf("%.2f", $updated_amount / 100) . ' ' . $order_details['transaction_details']['currency'].' ' . sprintf($this->language->get('sepa_amount_update2'), date('Y-m-d'), date('H:i:s'));
+ }
+
+ $order_details['transaction_details']['amount'] = $updated_amount;
+ $order_details['transaction_details']['total_amount'] = $updated_amount;
+
+ $novalnet_transactions = array(
+ 'transaction_details' => "'" . json_encode($order_details['transaction_details']) . "'",
+ 'gateway_status' => $response['tid_status'],
+ );
+
+ if($order_details['payment_id'] == '27') {
+ $novalnet_response = $order_details['additional_details'];
+ $novalnet_response['tid'] = $order_details['tid'];
+
+ $order_details['additional_details']['due_date'] = trim($this->request->post['dueDateUpdate']);
+
+ $novalnet_transactions['additional_details'] = "'" . addslashes(json_encode($order_details['additional_details'])) . "'";
+ $novalnet_response['amount'] = $updated_amount;
+ $novalnet_response['shop_tid'] = $novalnet_response['tid'];
+ $novalnet_response['currency'] = $order_details['transaction_details']['currency'];
+ $novalnet_response['due_date'] = $due_date;
+ $novalnet_response['order_no'] = $this->request->request['order_no'];
+
+ $invoice_details = array(
+ 'amount' => $order_details['transaction_details']['amount'] / 100,
+ 'currency' => $order_details['transaction_details']['currency'],
+ );
+ $order_details['novalnet_comments'] .= '", {
+ value: tariff_val,
+ text: jQuery.trim(hash_result_name)
+ }));
+ if (selected_value != null && selected_value != undefined && selected_value == tariff_val) {
+ jQuery("#input-payment-novalnet-tariff-id").val(selected_value).attr("selected", "selected");
+ }
+ }
+ jQuery("#ajax_complete").val('true');
+ jQuery("#input-payment-novalnet-merchant-id").val(response.vendor_id);
+ jQuery("#input-payment-novalnet-authcode").val(response.auth_code);
+ jQuery("#input-payment-novalnet-project-id").val(response.product_id);
+ jQuery("#input-payment-novalnet-access-key").val(response.access_key);
+ jQuery("#input-payment-novalnet-client-key").val(response.client_key);
+ return true;
+}
diff --git a/admin/view/javascript/novalnet/novalnet_extension.js b/admin/view/javascript/novalnet/novalnet_extension.js
new file mode 100644
index 0000000..37dfc8d
--- /dev/null
+++ b/admin/view/javascript/novalnet/novalnet_extension.js
@@ -0,0 +1,187 @@
+/**
+ * Novalnet global configuration script
+ * By Novalnet AG (https://www.novalnet.de)
+ * Copyright (c) Novalnet AG
+ */
+jQuery(document).ready(function() {
+
+ $('#radio-refund-payment-type-none').prop('checked', true);
+ $('#input-update-amount').on('keypress', function(e){
+ var regex = new RegExp("^[0-9\b]+$");
+ var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);
+ if (!regex.test(str)) {
+ return false;
+ }
+ });
+
+ /** Handle manage transaction **/
+ $('#button-novalnet-manage-transaction').on('click', function() {
+ $('.text-danger').remove();
+ if($('#select-transaction-status').val() == ''){
+ $('#select-transaction-status').after(''+$('#novalnet-error-text-status').val()+'
');
+ return false;
+ }
+ var message = ($('#select-transaction-status').val() == 100) ? $('#warning-capture').val() : $('#warning-cancel').val();
+ if (!confirm(message)) {
+ return false;
+ }
+ sendRequest('captureVoid', 'novalnet-manage-transaction');
+ });
+
+ /** Handle amount refund **/
+ $('#button-novalnet-amount-refund').on('click', function() {
+
+ $('.text-danger').remove();
+ if(Number($('#input-refund-amount').val()) == '') {
+ $('#input-refund-amount').after(''+$('#novalnet-error-amount-invalid').val()+'
');
+ return false;
+ }
+
+ if (!confirm($('#warning-refund').val())) {
+ return false;
+ }
+ sendRequest('amountRefund', 'novalnet-amount-refund');
+ });
+
+ /** Handle amount book **/
+ $('#button-novalnet-amount-book').on('click', function() {
+ $('.text-danger').remove();
+ if(Number($('#input-book-amount').val()) == '') {
+ $('#input-book-amount').after(''+$('#novalnet-error-amount-invalid').val()+'
');
+ return false;
+ }
+
+ if (!confirm($('#warning-amount-book').val())) {
+ return false;
+ }
+
+ sendRequest('amountBooking', 'novalnet-amount-book');
+ });
+
+ /** Handle amount update **/
+ $('#button-novalnet-amount-update').click(function(){
+ $('.text-danger').remove();
+
+ if(Number($('#input-update-amount').val()) == '') {
+ $('#input-update-amount').after(''+$('#novalnet-error-amount-invalid').val()+'
');
+ return false;
+ }
+
+ $('.text-danger').remove();
+ if($('#input-due-date').length && !isValidDate($('#input-due-date').val())) {
+ $('#input-due-date').after(''+$('#novalnet-error-due-date').val()+'
');
+ return false;
+ }
+
+ if($('#input-expiry-date').length && !isValidDate($('#input-expiry-date').val())) {
+ $('#input-expiry-date').after(''+$('#novalnet-error-due-date').val()+'
');
+ return false;
+ }
+
+ if($('#input-expiry-date').length) {
+ var selectedDate = new Date($('#input-expiry-date').val());
+ }
+ else {
+ var selectedDate = new Date($('#input-due-date').val());
+ }
+ var currentDate = new Date();
+
+ $('.text-danger').remove();
+ if (selectedDate < currentDate) {
+ if($('#input-expiry-date').length) {
+ $('#input-expiry-date').after(''+$('#novalnet-error-due-date-future').val()+'
');
+ }
+ else {
+ $('#input-due-date').after(''+$('#novalnet-error-due-date-future').val()+'
');
+ }
+ return false;
+ }
+ if (!confirm($('#warning-amount-update').val())) {
+ return false;
+ }
+ sendRequest('amountUpdate', 'novalnet-amount-update');
+ });
+
+ if($('#input-due-date').length){
+ $('#input-due-date').datetimepicker({
+ pickDate: true,
+ pickTime: false,
+ format: 'yy-mm-dd'
+ });
+ $('.date').datetimepicker({
+ pickTime: false
+ });
+ }
+
+ if($('#input-expiry-date').length){
+ $('#input-expiry-date').datetimepicker({
+ pickDate: true,
+ pickTime: false,
+ format: 'yy-mm-dd'
+ });
+ $('.date').datetimepicker({
+ pickTime: false
+ });
+ }
+});
+
+/** Validate account holder.**/
+function sepa_validation(event){
+ var keycode = ('which' in event) ? event.which : event.keyCode;
+ var reg = /^(?:[A-Za-z0-9]+$)/;
+ if(event.target.id == 'input-account-holder')
+ reg = /[^0-9\[\]\/\\#,+@!^()$~%'"=:;<>{}\_\|*?`]/g;
+ return (reg.test(String.fromCharCode(keycode)) || keycode === 0 || keycode === 8) ? true : false;
+}
+
+/** Validate due date.**/
+function isValidDate(dueDate) {
+ if(dueDate == '')
+ return false;
+ var rxDatePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/; //Declare Regex
+ var dtArray = dueDate.match(rxDatePattern); // is format OK?
+ if (dtArray == null)
+ return false;
+
+ //Checks for yyyy/mm/dd format.
+ dtYear = dtArray[1];
+ dtMonth = dtArray[3];
+ dtDay = dtArray[5];
+ if (dtMonth < 1 || dtMonth > 12)
+ return false;
+ else if (dtDay < 1 || dtDay> 31)
+ return false;
+ else if ((dtMonth==4 || dtMonth==6 || dtMonth==9 || dtMonth==11) && dtDay ==31)
+ return false;
+ else if (dtMonth == 2)
+ {
+ var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
+ if (dtDay> 29 || (dtDay ==29 && !isleap))
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Handle api response
+ */
+function api_response(json, form){
+ if(json['error']) {
+ $('#'+form).before(''+json['error']+'×
');
+ return false;
+ } else if (json['success']) {
+ $('.row').before(''+json['success']+'×
');
+ $('html, body').animate({scrollTop: '0px'}, 0);
+ setTimeout(function () {
+ location.reload(true);
+ }, 500);
+ }
+}
+
+/**
+ * Allow only an integer value
+ */
+function isNumberKey(evt){
+ var charCode = (evt.which) ? evt.which : evt.keyCode
+ return (!(charCode > 31 && (charCode < 48 || charCode > 57)));
+}
diff --git a/admin/view/stylesheet/novalnet.css b/admin/view/stylesheet/novalnet.css
new file mode 100644
index 0000000..79d7c47
--- /dev/null
+++ b/admin/view/stylesheet/novalnet.css
@@ -0,0 +1,6 @@
+.nn_div{
+ margin-top: -2.8% !important;
+}
+input[name="novalnet_cc_iframe_standard_css_text"]{
+ width:16% !important;
+}
\ No newline at end of file
diff --git a/admin/view/template/extension/payment/novalnet.twig b/admin/view/template/extension/payment/novalnet.twig
new file mode 100644
index 0000000..4111666
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet.twig
@@ -0,0 +1,204 @@
+{{ header }} {{column_left}}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+ {{ entry_admin_portal_src }}
+
+
+
+
+
+
+
+{{ footer }}
+
diff --git a/admin/view/template/extension/payment/novalnet_cashpayment.twig b/admin/view/template/extension/payment/novalnet_cashpayment.twig
new file mode 100644
index 0000000..8ae8972
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_cashpayment.twig
@@ -0,0 +1,114 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_cc.twig b/admin/view/template/extension/payment/novalnet_cc.twig
new file mode 100644
index 0000000..8a74818
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_cc.twig
@@ -0,0 +1,198 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ alert }}
+
+
+
+ {{ text_iframe_configuration }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{ footer }}
+
diff --git a/admin/view/template/extension/payment/novalnet_eps.twig b/admin/view/template/extension/payment/novalnet_eps.twig
new file mode 100644
index 0000000..3df1319
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_eps.twig
@@ -0,0 +1,94 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_giropay.twig b/admin/view/template/extension/payment/novalnet_giropay.twig
new file mode 100644
index 0000000..13e28dd
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_giropay.twig
@@ -0,0 +1,94 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_ideal.twig b/admin/view/template/extension/payment/novalnet_ideal.twig
new file mode 100644
index 0000000..0e833b9
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_ideal.twig
@@ -0,0 +1,94 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_instant_bank_transfer.twig b/admin/view/template/extension/payment/novalnet_instant_bank_transfer.twig
new file mode 100644
index 0000000..be06d21
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_instant_bank_transfer.twig
@@ -0,0 +1,94 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_invoice.twig b/admin/view/template/extension/payment/novalnet_invoice.twig
new file mode 100644
index 0000000..6a3767e
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_invoice.twig
@@ -0,0 +1,261 @@
+{{ header }}{{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
+
diff --git a/admin/view/template/extension/payment/novalnet_online_bank_transfer.twig b/admin/view/template/extension/payment/novalnet_online_bank_transfer.twig
new file mode 100644
index 0000000..b9281dd
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_online_bank_transfer.twig
@@ -0,0 +1,94 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_order.twig b/admin/view/template/extension/payment/novalnet_order.twig
new file mode 100644
index 0000000..f4a8124
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_order.twig
@@ -0,0 +1,157 @@
+
+
+{% if show_manage_transaction is not empty %}
+
+ {{ text_manage_transaction_process }}
+
+
+
+
+
+
+
+
+ {{ text_update }}
+
+
+
+{% endif %}
+{% if show_amount_book is not empty %}
+
+ {{ text_booking_transaction }}
+
+
+
+
+
+
+
+ {{ text_book }}
+
+
+
+{% endif %}
+
+{% if show_refund is not empty %}
+
+ {{ text_refund_process }}
+
+
+
+
+
+
+ {% if show_refund_reference is not empty %}
+
+ {% endif %}
+
+ {{ text_update }}
+
+
+
+{% endif %}
+
+{% if show_amount_update is not empty %}
+
+ {% if order_details.payment_id == 59 %}
+ {{ text_amount_expiry_date_update }}
+ {% elseif order_details.payment_id == 27 %}
+ {{ text_refund_amount_duedate_change }}
+ {% else %}
+ {{ text_amount_update }}
+ {% endif %}
+
+
+
+
+
+
+
+ {% if order_details.payment_id == 27 %}
+
+ {% elseif order_details.payment_id == 59 %}
+
+ {% else %}
+
+ {% endif %}
+
+ {% if show_due_date_update is not empty %}
+
+ {% endif %}
+ {% if show_amount_expiry_date_update is not empty %}
+
+ {% endif %}
+
+ {{ text_update }}
+
+
+
+{% endif %}
+
diff --git a/admin/view/template/extension/payment/novalnet_paypal.twig b/admin/view/template/extension/payment/novalnet_paypal.twig
new file mode 100644
index 0000000..6291d1e
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_paypal.twig
@@ -0,0 +1,179 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+
+ {{ entry_paypal_admin_portal_src }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{ footer }}
+
diff --git a/admin/view/template/extension/payment/novalnet_prepayment.twig b/admin/view/template/extension/payment/novalnet_prepayment.twig
new file mode 100644
index 0000000..b03e925
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_prepayment.twig
@@ -0,0 +1,126 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
+
+
diff --git a/admin/view/template/extension/payment/novalnet_przelewy24.twig b/admin/view/template/extension/payment/novalnet_przelewy24.twig
new file mode 100644
index 0000000..80a6cc1
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_przelewy24.twig
@@ -0,0 +1,107 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
diff --git a/admin/view/template/extension/payment/novalnet_sepa.twig b/admin/view/template/extension/payment/novalnet_sepa.twig
new file mode 100644
index 0000000..c494bac
--- /dev/null
+++ b/admin/view/template/extension/payment/novalnet_sepa.twig
@@ -0,0 +1,244 @@
+{{ header }} {{ column_left }}
+
+
+
+ {% if error_warning %}
+
{{ error_warning }}
+ ×
+
+ {% endif %}
+
+
+
+
+{{ footer }}
+
diff --git a/admin/view/template/sale/novalnet_recurring.twig b/admin/view/template/sale/novalnet_recurring.twig
new file mode 100644
index 0000000..4e7fbc2
--- /dev/null
+++ b/admin/view/template/sale/novalnet_recurring.twig
@@ -0,0 +1,51 @@
+{% if next_subs_cycle != '0000-00-00' %}
+ {{ text_next_charging_date }} {{ next_subs_cycle }}
+
+{% endif %}
+
+{{ text_recurring_orders }}
+
+
+
+
+ {{ text_novalnet_TID }}
+ {{ text_novalnet_amount }}
+ {{ text_payment_method }}
+ {{ text_transaction_details }}
+
+
+
+ {% for value in recurring_details %}
+
+ {{ value.tid }}
+ {{ value.amount }}
+ {{ payment_method }}
+ {{ value.transaction_details }}
+
+ {% endfor %}
+
+
+
+
diff --git a/catalog/controller/callback/vendorScript.php b/catalog/controller/callback/vendorScript.php
new file mode 100644
index 0000000..8b43cde
--- /dev/null
+++ b/catalog/controller/callback/vendorScript.php
@@ -0,0 +1,1076 @@
+ array(
+ 'CREDITCARD',
+ 'CREDITCARD_BOOKBACK',
+ 'CREDITCARD_CHARGEBACK',
+ 'CREDIT_ENTRY_CREDITCARD',
+ 'DEBT_COLLECTION_CREDITCARD',
+ 'SUBSCRIPTION_STOP',
+ 'SUBSCRIPTION_REACTIVATE',
+ 'TRANSACTION_CANCELLATION',
+ ),
+ 'novalnet_sepa' => array(
+ 'DIRECT_DEBIT_SEPA',
+ 'RETURN_DEBIT_SEPA',
+ 'SUBSCRIPTION_STOP',
+ 'SUBSCRIPTION_REACTIVATE',
+ 'DEBT_COLLECTION_SEPA',
+ 'CREDIT_ENTRY_SEPA',
+ 'GUARANTEED_DIRECT_DEBIT_SEPA',
+ 'GUARANTEED_SEPA_BOOKBACK',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'TRANSACTION_CANCELLATION'
+ ),
+ 'novalnet_ideal' => array(
+ 'IDEAL',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'ONLINE_TRANSFER_CREDIT',
+ 'REVERSAL',
+ 'CREDIT_ENTRY_DE',
+ 'DEBT_COLLECTION_DE',
+ ),
+ 'novalnet_instant_bank_transfer' => array(
+ 'ONLINE_TRANSFER',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'ONLINE_TRANSFER_CREDIT',
+ 'REVERSAL',
+ 'CREDIT_ENTRY_DE',
+ 'DEBT_COLLECTION_DE',
+ ),
+
+ 'novalnet_paypal' => array(
+ 'PAYPAL',
+ 'SUBSCRIPTION_STOP',
+ 'SUBSCRIPTION_REACTIVATE',
+ 'PAYPAL_BOOKBACK',
+ 'TRANSACTION_CANCELLATION',
+
+ ), 'novalnet_prepayment' => array(
+ 'INVOICE_START',
+ 'INVOICE_CREDIT',
+ 'SUBSCRIPTION_STOP',
+ 'SUBSCRIPTION_REACTIVATE',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ ),
+ 'novalnet_invoice' => array(
+ 'INVOICE_START',
+ 'GUARANTEED_INVOICE',
+ 'GUARANTEED_INVOICE_BOOKBACK',
+ 'INVOICE_CREDIT',
+ 'SUBSCRIPTION_STOP',
+ 'SUBSCRIPTION_REACTIVATE',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'TRANSACTION_CANCELLATION',
+ 'CREDIT_ENTRY_DE',
+ 'DEBT_COLLECTION_DE',
+ ),
+ 'novalnet_eps' => array(
+ 'EPS',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'ONLINE_TRANSFER_CREDIT',
+ 'REVERSAL',
+ 'CREDIT_ENTRY_DE',
+ 'DEBT_COLLECTION_DE',
+ ),
+ 'novalnet_giropay' => array(
+ 'GIROPAY',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'ONLINE_TRANSFER_CREDIT',
+ 'REVERSAL',
+ 'CREDIT_ENTRY_DE',
+ 'DEBT_COLLECTION_DE',
+ ),
+ 'novalnet_przelewy24' => array(
+ 'PRZELEWY24',
+ 'PRZELEWY24_REFUND',
+ 'TRANSACTION_CANCELLATION'
+ ),
+ 'novalnet_cashpayment' => array(
+ 'CASHPAYMENT',
+ 'CASHPAYMENT_CREDIT',
+ 'CASHPAYMENT_REFUND'
+ ),
+ 'novalnet_online_bank_transfer' => array(
+ 'ONLINE_BANK_TRANSFER',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'ONLINE_TRANSFER_CREDIT',
+ 'REVERSAL',
+ 'DEBT_COLLECTION_DE',
+ )
+ );
+
+ /** @Array Mandatory Parameters */
+ protected $required_params = array(
+ 'vendor_id',
+ 'tid',
+ 'payment_type',
+ 'status'
+ );
+
+ /** @Array Captured parameters */
+ protected $capture_params = array();
+
+ /** @Array Get transaction details */
+ protected $transaction_history = array();
+
+ /** @Array Novalnet success codes */
+ protected $success_code = array(
+ 'PAYPAL' => array(
+ '100',
+ '90',
+ '85'
+ ),
+ 'INVOICE_START' => array(
+ '100',
+ '91'
+ ),
+ 'GUARANTEED_INVOICE' => array(
+ '100',
+ '91',
+ '75'
+ ),
+ 'CREDITCARD' => array(
+ '100',
+ '98'
+ ),
+ 'DIRECT_DEBIT_SEPA' => array(
+ '100',
+ '99'
+ ),
+ 'GUARANTEED_DIRECT_DEBIT_SEPA' => array(
+ '100',
+ '99',
+ '75',
+ ),
+ 'ONLINE_TRANSFER' => array(
+ '100'
+ ),
+ 'GIROPAY' => array(
+ '100'
+ ),
+ 'IDEAL' => array(
+ '100'
+ ),
+ 'EPS' => array(
+ '100'
+ ),
+ 'PRZELEWY24' => array(
+ '86',
+ '100'
+ ),
+ 'CASHPAYMENT' => array(
+ '100'
+ ),
+ 'ONLINE_BANK_TRANSFER' => array(
+ '100'
+ )
+
+ );
+
+ /**
+ * Initiate the vendor script process
+ *
+ * @param none
+ * @return none
+ */
+ public function index()
+ {
+ // Load language content.
+ $this->language->load('callback/vendorScript');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Get Novalnet callback configuration.
+ $this->test_mode = $this->config->get('payment_novalnet_callback_testmode');
+
+ // Get requested parameters.
+ $this->capture_params = array_map('trim', $_REQUEST);
+
+ // Authenticating the server request based on IP.
+ $this->validateIpAddress();
+
+ if (!empty($this->capture_params['payment_type']) && $this->capture_params['payment_type'] != 'SUBSCRIPTION_STOP') {
+ array_push($this->required_params, 'amount');
+ }
+ // Get Parent TID.
+ $this->capture_params['shop_tid'] = !empty($this->capture_params['tid']) ? $this->capture_params['tid'] : '';
+ if (!empty($this->capture_params['subs_billing']) && $this->capture_params['subs_billing'] == 1) {
+ array_push($this->required_params, 'signup_tid');
+ $this->capture_params['shop_tid'] = $this->capture_params['signup_tid'];
+ } elseif (!empty($this->capture_params['payment_type']) && in_array($this->capture_params['payment_type'], array_merge($this->chargebacks, $this->collections))) {
+ array_push($this->required_params, 'tid_payment');
+ $this->capture_params['shop_tid'] = $this->capture_params['tid_payment'];
+ }
+ // Validate request parameters.
+ $this->validateCaptureParameters();
+
+ $this->load->model('account/order');
+ $order_details = $this->model_account_order->getOrderProducts($this->capture_params['order_no']);
+
+ // Order number check.
+ if ( empty( $order_details ) ) {
+ $this->send_critical_error_mail();
+ $this->displayMessage( 'Novalnet callback script order number not valid' );
+ }
+ // Get order details.
+ $this->transaction_history = $this->getOrderDetails();
+ if (!empty($this->transaction_history)) {
+
+ $check_status_code = ($this->capture_params['status'] == '100' && $this->capture_params['tid_status'] == '100');
+
+ // Transaction cancellation process.
+ $this->transaction_cancellation();
+
+ // Handle second level process.
+ if ($this->transaction_history['payment_level'] == 2 && $check_status_code) {
+ $this->secondLevelProcess();
+ }
+
+ // Handle first level process.
+ if ($this->transaction_history['payment_level'] == 1 && $check_status_code) {
+ $this->firstLevelProcess();
+ }
+
+ // Handle zero level process.
+ if ($this->transaction_history['payment_level'] == 0 && $this->success_code[$this->capture_params['payment_type']]) {
+ $this->zeroLevelProcess();
+ }
+
+
+ if (($this->capture_params['status'] != '100' || $this->capture_params['tid_status'] != '100') && $this->capture_params['payment_type'] != 'novalnet_przelewy24') {
+ $this->displayMessage('Novalnet callback received. Status (' . $this->capture_params['status'] . ') is not valid');
+ } else {
+ $this->displayMessage('Novalnet callback script executed already');
+ }
+ } else {
+ $this->displayMessage('Order Reference not exist!');
+ }
+ }
+
+ /**
+ * Perform level 2 payment process
+ *
+ * @param none
+ * @return none
+ */
+ public function secondLevelProcess()
+ {
+ if (in_array($this->capture_params['payment_type'], array('CREDIT_ENTRY_CREDITCARD', 'DEBT_COLLECTION_CREDITCARD', 'CREDIT_ENTRY_SEPA', 'DEBT_COLLECTION_SEPA', 'GUARANTEED_DEBT_COLLECTION_SEPA', 'CREDIT_ENTRY_DE', 'DEBT_COLLECTION_DE'))) {
+ $callback_comments = $this->language->get('text_success_callback1') . $this->capture_params['shop_tid'] . $this->language->get('text_success_callback2') . sprintf('%.2f', ($this->capture_params['amount'] / 100)) . ' ' . $this->capture_params['currency'] . $this->language->get('text_success_callback3') . date('Y-m-d H:i:s') . $this->language->get('text_success_callback4') . $this->capture_params['tid'];
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $callback_comments,
+ 'orders_status_id' => $this->transaction_history['current_order_status']
+ ));
+ // Send notification mail.
+ $this->sendNotificationMail($callback_comments);
+ $this->displayMessage($callback_comments);
+ }
+ if (isset($this->transaction_history['order_paid_amount']) && isset($this->transaction_history['transaction_details']['total_amount']) && $this->transaction_history['order_paid_amount'] < $this->transaction_history['transaction_details']['total_amount']) {
+ // Form callback comments.
+ $callback_comments = $this->language->get('text_success_callback1') . $this->capture_params['shop_tid'] . $this->language->get('text_success_callback2') . sprintf('%.2f', ($this->capture_params['amount'] / 100)) . ' ' . $this->capture_params['currency'] . $this->language->get('text_success_callback3') . date('Y-m-d H:i:s') . $this->language->get('text_success_callback4') . $this->capture_params['tid'];
+
+
+ $total_paid_amount = ($this->transaction_history['order_paid_amount'] + $this->capture_params['amount']);
+
+ $paid_status = 'unpaid';
+
+ // Check for total paid amount.
+ if ($this->transaction_history['transaction_details']['total_amount'] <= $total_paid_amount) {
+
+ $paid_status = 'paid';
+
+ // Get callback order status ID.
+ $callback_status_id = (!empty($this->transaction_history['callback_order_status'])) ? $this->transaction_history['callback_order_status'] : $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_order_completion_status');
+
+ if ($this->capture_params['payment_type'] != 'ONLINE_TRANSFER_CREDIT') {
+
+ // Update order status for the order.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $callback_status_id
+ ), 'order_id=' . $this->transaction_history['order_no']);
+
+ // Update Transaction status for the order in Novalnet table.prepareNovalnetComments
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_transactions', array(
+ 'gateway_status' => $this->capture_params['tid_status']
+ ), 'order_no=' . $this->transaction_history['order_no']);
+ }
+ } else {
+ $callback_status_id = $this->transaction_history['current_order_status'];
+ }
+
+ $recurring_details = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'transaction_details', 'tid =' . $this->capture_params['shop_tid']);
+ if(empty($recurring_details['transaction_details'])){
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $callback_comments,
+ 'orders_status_id' => $callback_status_id
+ ));
+ } else {
+ // Update callback comments for the order in Novalnet recurring transaction table.
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_recurring_transactions', array(
+ 'transaction_details' => '"' . $recurring_details['transaction_details'] . ' ' . $callback_comments . ' ' . '"' ,
+ 'status' => '"' . $paid_status . '"'
+ ), 'tid =' . $this->capture_params['shop_tid']);
+ }
+
+ // Log callback process.
+ $this->logCallbackProcess();
+
+ // Send notification mail.
+ $this->sendNotificationMail($callback_comments);
+ $this->displayMessage($callback_comments);
+ }
+ $this->displayMessage('Callback Script executed already. Refer Order :' . (!empty($this->transaction_history['order_no']) ? $this->transaction_history['order_no'] : ''));
+ }
+
+ /**
+ * Perform level 1 payment process
+ *
+ * @param none
+ * @return none
+ */
+ public function firstLevelProcess()
+ {
+ $comments = (in_array($this->capture_params['payment_type'], array(
+ 'CREDITCARD_BOOKBACK',
+ 'PAYPAL_BOOKBACK',
+ 'REFUND_BY_BANK_TRANSFER_EU',
+ 'PRZELEWY24_REFUND',
+ 'CASHPAYMENT_REFUND',
+ 'GUARANTEED_INVOICE_BOOKBACK',
+ 'GUARANTEED_SEPA_BOOKBACK'
+ ))) ? $this->language->get('text_bookback') : $this->language->get('text_chargeback1');
+
+ // Form callback comments.
+ $callback_comments = $comments . $this->capture_params['tid_payment'] . $this->language->get('text_chargeback2') . sprintf('%.2f', ($this->capture_params['amount'] / 100)) . ' ' . $this->capture_params['currency'] . $this->language->get('text_success_callback3') . date("Y-m-d H:i:s") . $this->language->get('text_chargeback4') . $this->capture_params['tid'];
+
+ // Log callback process.
+ $this->logCallbackProcess();
+
+ $recurring_details = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'transaction_details', 'tid =' . $this->capture_params['shop_tid']);
+ if(empty($recurring_details['transaction_details'])){
+
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $callback_comments,
+ 'orders_status_id' => $this->transaction_history['current_order_status']
+ ));
+ } else {
+ // Update callback comments for the order in Novalnet recurring transaction table.
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_recurring_transactions', array(
+ 'transaction_details' => '"' . $recurring_details['transaction_details'] . ' ' . $callback_comments . '"',
+ ), 'tid =' . $this->capture_params['shop_tid']);
+ }
+ // Send notification mail.
+ $this->sendNotificationMail($callback_comments);
+ $this->displayMessage($callback_comments);
+ }
+
+ /**
+ * Perform level 0 payment process
+ *
+ * @param none
+ * @return none
+ */
+ public function zeroLevelProcess()
+ {
+ if(in_array($this->capture_params['payment_type'], array('INVOICE_START', 'DIRECT_DEBIT_SEPA', 'GUARANTEED_INVOICE', 'GUARANTEED_DIRECT_DEBIT_SEPA', 'CREDITCARD', 'PAYPAL')) && in_array($this->transaction_history['gateway_status'], array(75, 91, 99, 98, 85)) && in_array($this->capture_params['tid_status'], array(91, 99, 100))) {
+ // Get order information
+ $order_info = $this->model_extension_payment_novalnet->dbSelect('order', 'total, currency_value, currency_code', 'order_id =' . $this->transaction_history['order_no']);
+ $comments = '';
+ if($this->capture_params['tid_status'] == 100 && $this->capture_params['status'] == 100 && in_array($this->transaction_history['gateway_status'], array(91, 99, 98, 85))) {
+
+ $order_status =($this->capture_params['payment_type'] == 'GUARANTEED_INVOICE') ? $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_callback_order_status') : $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_order_completion_status');
+ // Update order status ID in shop order table.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $order_status
+ ), 'order_id=' . $this->transaction_history['order_no']);
+ if(in_array($this->capture_params['payment_type'], array('INVOICE_START', 'GUARANTEED_INVOICE'))) {
+ $callback = true;
+ $comments = $this->model_extension_payment_novalnet->prepareTransactionComments($this->capture_params, $this->transaction_history['payment_type']);
+ $comments .= $this->model_extension_payment_novalnet->prepareNovalnetComments($this->capture_params, $order_info,$callback);
+ if ($this->capture_params['payment_type'] == 'GUARANTEED_INVOICE') {
+ $this->sendPaymentNotificationMail($this->transaction_history['order_no'], $comments);
+ }
+ }
+ } else if($this->capture_params['payment_type'] == 'GUARANTEED_INVOICE' && $this->transaction_history['gateway_status'] == 75 && in_array($this->capture_params['tid_status'], array(91,100))) {
+ $order_status = ($this->capture_params['tid_status'] == 100) ? $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_callback_order_status') : $this->config->get('payment_novalnet_onhold_complete_status');
+ // Update order status ID in shop order table.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $order_status
+ ), 'order_id=' . $this->transaction_history['order_no']);
+ // Re-generate invoice comments
+ $callback = true;
+ $comments .= $this->model_extension_payment_novalnet->prepareTransactionComments($this->capture_params, $this->transaction_history['payment_type']);
+ $comments .= $this->model_extension_payment_novalnet->prepareNovalnetComments($this->capture_params, $order_info, $callback);
+ $this->sendPaymentNotificationMail($this->transaction_history['order_no'], $comments);
+ } else if($this->capture_params['payment_type'] == 'GUARANTEED_DIRECT_DEBIT_SEPA' && $this->transaction_history['gateway_status'] == 75 && in_array($this->capture_params['tid_status'], array(99,100))) {
+ $order_status = ($this->capture_params['tid_status'] == 100) ? $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_order_completion_status') : $this->config->get('payment_novalnet_onhold_complete_status');
+ // Update order status ID in shop order table.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $order_status
+ ), 'order_id=' . $this->transaction_history['order_no']);
+ $this->sendPaymentNotificationMail($this->transaction_history['order_no'], $comments);
+ } else {
+ $this->displayMessage('Novalnet callback script executed already');
+ }
+ if($this->transaction_history['gateway_status'] == 75 && in_array($this->capture_params['tid_status'], array(91, 99))) {
+ $comments .= ' ' .$this->language->get('text_guarantee_pending_to_onhold_message') . $this->capture_params['shop_tid'] . $this->language->get('text_success_callback3') . date('Y-m-d H:i:s');
+ }else if(in_array($this->transaction_history['gateway_status'], array(75, 91, 99, 98, 85)) && $this->capture_params['tid_status'] == 100) {
+ $comments .= 'The transaction has been confirmed successfully for the TID: ' .$this->capture_params['shop_tid']. ' on '. date('Y-m-d H:i:s');
+ }
+
+ // Update Transaction status in Novalnet table.
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_transactions', array(
+ 'gateway_status' => $this->capture_params['tid_status']
+ ), 'order_no=' . $this->transaction_history['order_no']);
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $comments,
+ 'orders_status_id' => $order_status
+ ));
+
+ // Send notification mail.
+ $this->sendNotificationMail($comments);
+ $this->displayMessage($comments);
+ } else if (in_array($this->capture_params['payment_type'], array( 'PAYPAL', 'PRZELEWY24' )) && $this->capture_params['tid_status'] == '100') {
+ if (empty($this->transaction_history['order_paid_amount'])) {
+ // Form callback comments.
+ $callback_comments = $this->language->get('text_success_callback1') . $this->capture_params['shop_tid'] . $this->language->get('text_success_callback2') . sprintf('%.2f', ($this->capture_params['amount'] / 100)) . ' ' . $this->capture_params['currency'] . $this->language->get('text_success_callback3') . date('Y-m-d H:i:s');
+
+ $callback_status = $this->config->get('payment_'.$this->transaction_history['payment_type'] . '_order_completion_status');
+
+ // Update order status ID in shop order table.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $callback_status
+ ), 'order_id=' . $this->transaction_history['order_no']);
+
+ $this->transaction_history['transaction_details']['total_amount'] = $this->transaction_history['transaction_details']['amount'] = $this->capture_params['amount'];
+
+ // Update Transaction status in Novalnet table.
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_transactions', array(
+ 'gateway_status' => $this->capture_params['tid_status'],
+ 'transaction_details' => "'" . json_encode($this->transaction_history['transaction_details']) . "'"
+ ), 'order_no=' . $this->transaction_history['order_no']);
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $callback_comments,
+ 'orders_status_id' => $callback_status
+ ));
+ // Log callback process.
+ $this->logCallbackProcess();
+ // Send notification mail.
+ $this->sendNotificationMail($callback_comments);
+ $this->displayMessage($callback_comments);
+ }
+ $this->displayMessage('Novalnet Callbackscript received. Order already Paid');
+ } else if($this->capture_params['payment_type'] == 'PRZELEWY24' && !in_array($this->capture_params['tid_status'], array('86', '100'))) {
+ $callback_comments = $this->language->get('transaction_cancel_message') . (!empty($this->capture_params['status_message']) ? $this->capture_params['status_message'] : (!empty($this->capture_params['status_text']) ? $this->capture_params['status_text'] : (!empty($this->capture_params['status_desc']) ? $this->capture_params['status_desc'] : $this->language->get('text_novalnet_error_code')) ));
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $callback_comments,
+ 'orders_status_id' => $this->config->get('payment_novalnet_cancel_status')
+ ));
+ $this->displayMessage($callback_comments);
+ } else {
+ $this->displayMessage('Novalnet Callbackscript received. Payment type ( ' . $this->capture_params['payment_type'] . ' ) is not applicable for this process!');
+ }
+ }
+
+ /**
+ * Log callback process in novalnet_callback_history table
+ *
+ * @param none
+ * @return none
+ */
+ public function logCallbackProcess()
+ {
+ $original_tid = !empty($this->transaction_history['tid']) ? $this->transaction_history['tid'] : $this->capture_params['tid'];
+ $this->model_extension_payment_novalnet->dbInsert('novalnet_merchant_script', array(
+ 'order_no',
+ 'original_tid',
+ 'callback_tid',
+ 'payment_type',
+ 'amount',
+ 'date'
+ ), array(
+ $this->db->escape($this->transaction_history['order_no']),
+ $this->db->escape($original_tid),
+ $this->db->escape($this->capture_params['tid']),
+ "'" . $this->db->escape($this->transaction_history['payment_type']) . "'",
+ $this->db->escape($this->capture_params['amount']),
+ "'" . date('Y-m-d H:i:s') . "'"
+ ));
+ }
+
+ /**
+ * Get order details
+ *
+ * @param none
+ * @return array
+ */
+ public function getOrderDetails()
+ {
+ // Get Transaction details.
+ $selected_details = $this->model_extension_payment_novalnet->dbSelect('novalnet_transactions', 'order_no, transaction_details, gateway_status, payment_type', 'tid =' . $this->capture_params['shop_tid']);
+ if(!empty($selected_details['transaction_details'])) {
+ $selected_details['transaction_details'] = (array)json_decode($selected_details['transaction_details']);
+ }
+ $order_id = !empty($this->capture_params['order_no']) ? $this->capture_params['order_no'] : '';
+ if (empty($selected_details)) {
+ // Handle communication failure.
+ $this->communicationFailureProcess($order_id);
+ // Handle online transfer credit.
+ if($this->capture_params['payment_type'] == 'ONLINE_TRANSFER_CREDIT'){
+ $selected_details = $this->model_extension_payment_novalnet->dbSelect('novalnet_transactions', 'order_no, transaction_details, payment_type', 'tid =' . $this->capture_params['shop_tid']);
+ if(!empty($selected_details['transaction_details'])) {
+ $selected_details['transaction_details'] = (array)json_decode($selected_details['transaction_details']);
+ }
+ }
+ }
+ // Validate order number.
+ if (!empty($selected_details['order_no']) && !empty($order_id) && $order_id != $selected_details['order_no']) {
+ $this->displayMessage('Novalnet callback received. Order Number is not valid.');
+ }
+ // Validate Payment type.
+ if (!empty($selected_details['payment_type']) && !in_array($this->capture_params['payment_type'], $this->payment_group[$selected_details['payment_type']])) {
+ $this->displayMessage('Novalnet callback received. Payment Type [' . $this->capture_params['payment_type'] . '] is not valid.');
+ }
+ // Assign further Transaction details.
+ if (!empty($selected_details['order_no'])) {
+ $selected_details['tid'] = $this->capture_params['shop_tid'];
+ $selected_details['current_order_status'] = $this->getCurrentOrderStatus($selected_details['order_no']);
+ $selected_details['callback_amount'] = $this->capture_params['amount'];
+ if (in_array($selected_details['payment_type'], array(
+ 'novalnet_invoice',
+ 'novalnet_prepayment',
+ 'novalnet_cashpayment',
+ ))) {
+ $selected_details['callback_order_status'] = $this->config->get('payment_'.$selected_details['payment_type'] . '_callback_order_status');
+ }
+ $selected_details['order_paid_amount'] = 0;
+
+ // Get payment level.
+ $selected_details['payment_level'] = $this->getPaymentLevelType();
+ if (in_array($selected_details['payment_level'], array(
+ 0,
+ 2
+ ))) {
+ $paid_amount = $this->model_extension_payment_novalnet->dbSelect('novalnet_merchant_script', 'sum(amount) as amount_total', 'original_tid =' . $selected_details['tid']);
+ $selected_details['order_paid_amount'] = $paid_amount['amount_total'];
+ }
+ }
+ return $selected_details;
+ }
+
+ /**
+ * Get current order status
+ *
+ * @param $order_id
+ * @return mixed
+ */
+ public function getCurrentOrderStatus($order_id)
+ {
+ $result = $this->model_extension_payment_novalnet->dbSelect('order', 'order_status_id', 'order_id =' . $order_id);
+ return (!empty($result['order_status_id'])) ? $result['order_status_id'] : '';
+ }
+
+ /**
+ * Get payment level type
+ *
+ * @param none
+ * @return integer
+ */
+ public function getPaymentLevelType()
+ {
+ if (in_array($this->capture_params['payment_type'], $this->payments)) {
+ return 0;
+ } elseif (in_array($this->capture_params['payment_type'], $this->chargebacks)) {
+ return 1;
+ } elseif (in_array($this->capture_params['payment_type'], $this->collections)) {
+ return 2;
+ }
+ }
+
+ /**
+ * Perform communication failure process
+ *
+ * @param $order_id
+ * @return none
+ */
+ public function communicationFailureProcess($order_id)
+ {
+ if ($order_id) {
+ $selected_details = $this->model_extension_payment_novalnet->dbSelect('order', 'customer_id, payment_code', 'order_id =' . $order_id);
+ $payment_type = $selected_details['payment_code'];
+ if (!in_array($this->capture_params['payment_type'], $this->payment_group[$payment_type])) {
+ $this->displayMessage('Novalnet callback received. Payment Type [' . $this->capture_params['payment_type'] . '] is not valid.');
+ }
+ if (!empty($this->capture_params['subs_id'])) {
+ $this->model_extension_payment_novalnet->dbInsert('novalnet_subscriptions', array(
+ 'subs_id',
+ 'tid',
+ 'signup_date',
+ 'order_no',
+ 'date'
+ ), array(
+ $this->db->escape($this->capture_params['subs_id']),
+ $this->db->escape($this->capture_params['shop_tid']),
+ "'" . date('Y-m-d H:i:s') . "'",
+ $this->db->escape($order_id),
+ "'" . date('Y-m-d H:i:s') . "'"
+ ));
+ }
+ $payment_id = $this->getPaymentKey($payment_type);
+ $this->insertTransactionDetails(array(
+ 'order_no' => $this->capture_params['order_no'],
+ 'tid' => $this->capture_params['shop_tid'],
+ 'gateway_status' => $this->capture_params['tid_status'],
+ 'payment_type' => "'" . $payment_type . "'",
+ 'payment_id' => $payment_id,
+ 'customer_id' => $selected_details['customer_id'],
+ 'transaction_details' => "'" . json_encode(array(
+ 'amount' => $this->capture_params['amount'],
+ 'total_amount' => $this->capture_params['amount'],
+ 'currency' => $this->capture_params['currency'],
+ )) . "'",
+ 'date' => "'" . date('Y-m-d H:i:s') . "'"
+ ));
+ $payment_order_status = '"' . $payment_type . '_order_completion_status"';
+ if (($payment_type == 'novalnet_paypal' && $this->capture_params['tid_status'] == 90) || ($payment_type == 'novalnet_przelewy24' && $this->capture_params['tid_status'] == 86)) {
+ $payment_order_status = '"' . $payment_type . '_pending_order_status"';
+ }
+ $comments = $this->language->get('text_' . $payment_type . '_title') . PHP_EOL;
+ $comments .= $this->language->get('text_novalnet_transactionid') . $this->capture_params['shop_tid'];
+ $comments .= ($this->capture_params['test_mode']) ? ' ' . $this->language->get('text_novalnet_testorder') : '';
+ $order_status = $this->config->get('payment_'. $payment_type . '_order_completion_status');
+ if ((!empty($this->capture_params['tid_status']) && !in_array($this->capture_params['tid_status'], array( 100, 90, 91, 98, 99, 86, 85 ))) || ($this->capture_params['status'] != 100)) {
+ $order_status = $this->config->get('payment_novalnet_cancel_status');
+ $this->capture_params['amount'] = 0;
+ $comments .= ' ' . (!empty($this->capture_params['status_message']) ? $this->capture_params['status_message'] : (!empty($this->capture_params['status_text']) ? $this->capture_params['status_text'] : (!empty($this->capture_params['status_desc']) ? $this->capture_params['status_desc'] : $this->language->get('text_novalnet_error_code'))));
+ } else {
+ $order_status = $payment_order_status;
+ }
+ $status_info = array(
+ 'orders_status_id' => $order_status,
+ 'comments' => $comments,
+ 'order_no' => $order_id
+ );
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $order_status
+ ), 'order_id=' . $order_id);
+ $this->model_extension_payment_novalnet->dbInsert('novalnet_merchant_script', array(
+ 'order_no',
+ 'original_tid',
+ 'callback_tid',
+ 'payment_type',
+ 'amount',
+ 'date'
+ ), array(
+ $this->db->escape($order_id),
+ $this->db->escape($this->capture_params['shop_tid']),
+ $this->db->escape($this->capture_params['shop_tid']),
+ "'" . $this->db->escape($payment_type) . "'",
+ (in_array($payment_type, array('novalnet_invoice', 'novalnet_prepayment', 'novalnet_cashpayment')) || ($payment_type =='novalnet_paypal' && $this->capture_params['tid_status'] == 90 ) || ($this->capture_params['payment_type'] == 'ONLINE_TRANSFER_CREDIT')) ? 0 : $this->db->escape($this->capture_params['amount']),
+ "'" . date('Y-m-d H:i:s') . "'"
+ ));
+ $this->updateCallbackComments($status_info);
+ $order_id = $this->capture_params['order_no'];
+ $this->transaction_history['tid'] = $this->capture_params['shop_tid'];
+ $this->sendNotificationMail($comments);
+ if($this->capture_params['payment_type'] != 'ONLINE_TRANSFER_CREDIT'){
+ $this->displayMessage($comments);
+ } else {
+ return true;
+ }
+ } else {
+ $this->displayMessage('Transaction mapping failed');
+ }
+ }
+
+ /**
+ * Insert transaction details
+ *
+ * @param $transaction_details
+ * @return none
+ */
+ public function insertTransactionDetails($transaction_details) {
+ $transaction_details['payment_configurations'] = "'" . json_encode($this->model_extension_payment_novalnet->getMerchantDetails()) . "'";
+ $columns = $values = array();
+ foreach($transaction_details as $key => $value){
+ $columns[] = $key;
+ $values[] = $value;
+ }
+ $this->model_extension_payment_novalnet->dbInsert('novalnet_transactions', $columns, $values);
+ }
+
+ /**
+ * Get payment key
+ *
+ * @param $payment_type
+ * @return integer
+ */
+ public function getPaymentKey($payment_type)
+ {
+ $payment_key = array(
+ 'novalnet_instant_bank_transfer' => 33,
+ 'novalnet_ideal' => 49,
+ 'novalnet_paypal' => 34,
+ 'novalnet_eps' => 50,
+ 'novalnet_cc' => 6,
+ 'novalnet_przelewy24' => 78,
+ 'novalnet_sepa' => 37,
+ 'novalnet_invoice' => 27,
+ 'novalnet_prepayment' => 27,
+ 'novalnet_giropay' => 69,
+ 'novalnet_cashpayment' => 59,
+ 'novalnet_online_bank_transfer'=>113,
+ );
+ return ($payment_key[$payment_type]);
+ }
+
+ /**
+ * validate request parameters
+ *
+ * @param none
+ * @return none
+ */
+ public function validateCaptureParameters()
+ {
+ foreach ($this->required_params as $value) {
+ if (empty($this->capture_params[$value])) {
+ $this->displayMessage('Required param(' . $value . ') missing!');
+ } else if (in_array($value, array(
+ 'tid',
+ 'tid_payment',
+ 'signup_tid'
+ )) && !preg_match('/^\d{17}$/', $this->capture_params[$value])) {
+ $this->displayMessage('Novalnet callback received. Invalid TID [' . $this->capture_params[$value] . '] for Order.');
+ }
+ }
+ if (!in_array($this->capture_params['payment_type'], array_merge($this->collections, $this->chargebacks, $this->payments, $this->subscriptions, array('TRANSACTION_CANCELLATION') ))) {
+ $this->displayMessage('Novalnet callback received. Payment type [' . $this->capture_params['payment_type'] . '] is mismatched!');
+ }
+ }
+
+ /**
+ * Update callback comments in order_history table
+ *
+ * @param $data
+ * @return none
+ */
+ public function updateCallbackComments($data)
+ {
+ $comments = ($data['comments'] != '') ? $data['comments'] : '';
+ $this->model_extension_payment_novalnet->dbInsert('order_history', array(
+ 'comment',
+ 'order_status_id',
+ 'order_id',
+ 'notify',
+ 'date_added'
+ ), array(
+ "'" . $this->db->escape($comments) . "'",
+ $this->db->escape($data['orders_status_id']),
+ $this->db->escape($data['order_no']),
+ 1,
+ "'" . date('Y-m-d h:i:s') . "'"
+ ));
+ }
+
+ /**
+ * Transaction cancellation.
+ *
+ * @param none
+ * @return none
+ */
+ public function transaction_cancellation(){
+ // Get Transaction details.
+ $selected_details = $this->model_extension_payment_novalnet->dbSelect('novalnet_transactions', 'gateway_status', 'tid =' . $this->capture_params['shop_tid']);
+
+ if ( 'TRANSACTION_CANCELLATION' === $this->capture_params ['payment_type'] && in_array( $selected_details['gateway_status'], array('75','91','99','98','85', '90', '86' )) || (in_array( $this->capture_params['payment_type'], array('GUARANTEED_INVOICE', 'GUARANTEED_DIRECT_DEBIT_SEPA' )) && $this->capture_params ['tid_status'] == '103' && in_array( $selected_details['gateway_status'], array('75','91','99','98','85', '90', '86' )))) {
+ $novalnet_comments ='The transaction has been canceled on ' .date('Y-m-d H:i:s') . '.';
+ // Update order status ID in shop order table.
+ $this->model_extension_payment_novalnet->dbUpdate('order', array(
+ 'order_status_id' => $this->config->get('payment_novalnet_cancel_status'),
+ ), 'order_id=' . $this->transaction_history['order_no']);
+ // Update Transaction status for the order in Novalnet table.
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_transactions', array(
+ 'gateway_status' => $this->capture_params['tid_status']
+ ), 'order_no=' . $this->transaction_history['order_no']);
+ // Update callback comments.
+ $this->updateCallbackComments(array(
+ 'order_no' => $this->transaction_history['order_no'],
+ 'comments' => $novalnet_comments,
+ 'orders_status_id' => $this->config->get('payment_novalnet_cancel_status')
+ ));
+ $this->displayMessage( $novalnet_comments );
+ }
+ }
+
+ /**
+ * Send notification mail to merchant
+ *
+ * @param $callback_comments
+ * @return none
+ */
+ public function sendNotificationMail($callback_comments)
+ {
+ if ($this->config->get('payment_novalnet_callback_mail') == 'yes') {
+ $email_from_name = $this->config->get('config_email');
+ $email_to = (($this->config->get('payment_novalnet_callback_to_addr') != '') ? $this->config->get('payment_novalnet_callback_to_addr') : $email_from_name);
+ $email_subject = 'Novalnet Callback script notification ';
+ $email_content = $callback_comments;
+ $email_content = str_replace(' ', ' ', $email_content);
+ $email_content = str_replace('', ' ', $email_content);
+ $email_content = str_replace(' ', ' ', $email_content);
+ $email_content = str_replace('', ' ', $email_content);
+ $email_content = str_replace(' ', ' ', $email_content);
+ // Send Callback notification E-mail.
+ if (preg_match('/^[^\@]+@.*\.[a-z]{2,6}$/i', $email_to)) {
+ $mail = new Mail();
+ $mail_bcc_addr = $this->config->get('payment_novalnet_callback_bcc_addr');
+ if(!empty($mail_bcc_addr)){
+ $bcc_address = explode(',', $this->config->get('payment_novalnet_callback_bcc_addr'));
+ foreach($bcc_address as $email_bcc) {
+ $mail->parameter .= 'Bcc: <' . $email_bcc . '>' . PHP_EOL;
+ }
+ }
+ $mail->setTo($email_to);
+ $mail->setFrom($email_from_name);
+ $mail->setSender($email_from_name);
+ $mail->setSubject($email_subject);
+ $mail->setText($email_content);
+ $mail->send();
+ }
+ }
+ }
+
+ /**
+ * Send critical error mail.
+ *
+ * @param none
+ * @return none
+ */
+ public function send_critical_error_mail()
+ {
+ if ( $this->capture_params ['status'] == '100' ) {
+ $email_from_name = $this->config->get('config_email');
+ $email_subject = 'Critical error on shop system ' . $this->config->get('config_template') . ': order not found for TID: ' . $this->capture_params ['shop_tid'];
+ // Define some variables to assign to template
+ $comments = 'Technic team,'.PHP_EOL . PHP_EOL.'Please evaluate this transaction and contact our Technic team and Backend team at Novalnet.' . PHP_EOL . PHP_EOL;
+ $comments .= 'Merchant ID: ' . $this->capture_params['vendor_id'] . PHP_EOL;
+ $comments .= 'Project ID: ' . $this->capture_params['product_id'] . PHP_EOL;
+ $comments .= 'TID: ' . $this->capture_params['shop_tid'] . PHP_EOL;
+ $comments .= 'TID status: ' . $this->capture_params['tid_status'] . PHP_EOL;
+ $comments .= 'Order no: ' . $this->capture_params['order_no'] . PHP_EOL;
+ $comments .= 'Payment type: ' . $this->capture_params['payment_type'] . PHP_EOL;
+ $comments .= 'E-mail: ' . $this->capture_params['email'] . PHP_EOL . PHP_EOL . PHP_EOL;
+ $comments .= 'Regards,'.PHP_EOL.'Novalnet Team';
+ $mail = new Mail();
+ $mail->setTo('technic@novalnet.de');
+ $mail->setFrom($email_from_name);
+ $mail->setSender($email_from_name);
+ $mail->setSubject($email_subject);
+ $mail->setText($comments);
+ $mail->send();
+ }
+ }
+
+ /**
+ * Validate IP address
+ *
+ * @param none
+ * @return none
+ */
+ public function validateIpAddress()
+ {
+ $real_host_ip = gethostbyname('pay-nn.de');
+ if (empty($real_host_ip)) {
+ $this->displayMessage('Novalnet HOST IP missing');
+ }
+ $client_ip =$this->getRemoteAddress($real_host_ip);
+
+ if (!empty($real_host_ip) && ! empty($client_ip)) {
+ if ($client_ip != $real_host_ip && $this->test_mode != 'yes') {
+ $this->displayMessage('Novalnet callback received. Unauthorised access from the IP ' . $client_ip);
+ }
+ }else {
+ $this->displayMessage('Unauthorised access from the IP. Host/recieved IP is empty');
+ }
+ }
+
+ /**
+ * Get remote address
+ *
+ * @param $novalnet_host_ip
+ *
+ * @return array
+ */
+ public function getRemoteAddress($novalnet_host_ip)
+ {
+ $ip_keys = [
+ 'HTTP_X_FORWARDED_HOST',
+ 'HTTP_X_REAL_IP',
+ 'HTTP_CLIENT_IP',
+ 'HTTP_X_FORWARDED_FOR',
+ 'HTTP_X_FORWARDED',
+ 'HTTP_X_CLUSTER_CLIENT_IP',
+ 'HTTP_FORWARDED_FOR',
+ 'HTTP_FORWARDED',
+ 'REMOTE_ADDR',
+ ];
+ foreach ($ip_keys as $key) {
+ if (array_key_exists($key, $_SERVER) === true) {
+ if (in_array($key, ['HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST'])) {
+ $forwarded_ip = !empty($_SERVER[$key]) ? explode(',', $_SERVER[$key]) : [];
+ return (in_array($novalnet_host_ip, $forwarded_ip)) ? $novalnet_host_ip : $_SERVER[$key];
+ }
+ return $_SERVER[$key];
+ }
+ }
+ }
+
+ /**
+ * Display the error message
+ *
+ * @param $message
+ * @return none
+ */
+ public function displayMessage($message)
+ {
+ echo mb_convert_encoding($message, 'ISO-8859-1', 'UTF-8');
+ exit;
+ }
+
+ /**
+ * Send Guaranteed invoice payment confirmation mail to end customer
+ *
+ * @param $order_id
+ * @param $transaction_comments
+ * @return none
+ */
+
+ public function sendPaymentNotificationMail($order_id , $transaction_comments)
+ {
+ $get_customer_details = $this->model_extension_payment_novalnet->dbSelect('order', 'customer_id, firstname, lastname, email', 'order_id =' . $order_id);
+ if (!empty($get_customer_details['email'])) {
+ $shop_name = !empty($this->config->get('config_name')) ? $this->config->get('config_name') : '';
+ $email_from_name = $this->config->get('config_email');
+ $email_to = $get_customer_details['email'];
+ $email_subject = 'Order Confirmation - Your Order '.$order_id.' with '.$shop_name.' has been confirmed!';
+ $email_content = '
+
+
+
+ Dear Mr./Ms./Mrs. '.$get_customer_details['firstname'].' '.$get_customer_details['lastname'].'
+ We are pleased to inform you that your order has been confirmed.
+ Subject: Order Confirmation - Your Order '.$order_id.' with '.$shop_name.' has been confirmed!
+ Payment Information:
+ '.$transaction_comments.'
+
+
+
+
+
+ ';
+ // Send Callback notification E-mail.
+ if (preg_match('/^[^\@]+@.*\.[a-z]{2,6}$/i', $email_to)) {
+ $mail = new Mail();
+ $mail->setTo($email_to);
+ $mail->setFrom($email_from_name);
+ $mail->setSender($email_from_name);
+ $mail->setSubject($email_subject);
+ $mail->setHtml($email_content);
+ $mail->send();
+ }
+ } else {
+ $this->displayMessage(['message' =>'Mail not sent.']);
+ }
+ }
+}
diff --git a/catalog/controller/extension/module/novalnet.php b/catalog/controller/extension/module/novalnet.php
new file mode 100644
index 0000000..f8bc570
--- /dev/null
+++ b/catalog/controller/extension/module/novalnet.php
@@ -0,0 +1,35 @@
+session->data['novalnet_sepa_max_time'])){
+ unset($this->session->data['novalnet_sepa_max_time']);
+ }
+ if(isset($this->session->data['novalnet_invoice_max_time'])){
+ unset($this->session->data['novalnet_invoice_max_time']);
+ }
+ if(isset($this->session->data['novalnet_invoice'])){
+ unset($this->session->data['novalnet_invoice']);
+ }
+ if(isset($this->session->data['novalnet_sepa'])){
+ unset($this->session->data['novalnet_sepa']);
+ }
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_cashpayment.php b/catalog/controller/extension/payment/novalnet_cashpayment.php
new file mode 100644
index 0000000..0e19825
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_cashpayment.php
@@ -0,0 +1,108 @@
+language->load('extension/payment/novalnet_cashpayment');
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_cashpayment');
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_cashpayment', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_cashpayment');
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_cashpayment');
+
+ // Form due date.
+ $cashpaymet_duedate = trim($this->config->get('payment_novalnet_cashpayment_slip_expiry_date'));
+ if (!empty($cashpaymet_duedate)) {
+ $parameters['cp_due_date'] = date('Y-m-d', mktime(0, 0, 0, date('m'), (date('d') + $cashpaymet_duedate), date('Y')));
+ }
+
+ // Perform payment call.
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+ // Validate paygate response.
+ if($this->model_extension_payment_novalnet->checkResponseStatus($server_response)) {
+ $server_response['additional_details'] = json_encode(array(
+ 'cp_due_date' => $server_response['cp_due_date'],
+ ));
+ $this->session->data['nn_test_mode'] = $server_response['test_mode'];
+ $this->session->data['cp_checkout_token'] = $server_response['cp_checkout_token'];
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, 'novalnet_cashpayment');
+ // Generate Novalnet comments.
+ $data['novalnet_comments'] .= $this->model_extension_payment_novalnet->prepareBarzahlenComments($server_response);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->json['success'] = $this->url->link('checkout/success');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_barzahlen_payment_description',
+ 'text_test_mode_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed',
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_cc.php b/catalog/controller/extension/payment/novalnet_cc.php
new file mode 100644
index 0000000..a625eeb
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_cc.php
@@ -0,0 +1,305 @@
+language->load('extension/payment/novalnet_cc');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_cc');
+
+ // Get one click shopping details.
+ $data = $this->model_extension_payment_novalnet->getShoppingTypeDetails($this->payment_method, $data);
+ $data['oneclick']= $this->config->get('payment_novalnet_cc_shopping_type');
+
+ // Add Credit Card additional details.
+ $data = $this->ccDetails($data);
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add Iframe style content.
+ $data = $this->getIframeStyleContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_cc', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_cc');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Get shopping type value.
+ $shopping_type = $this->config->get('payment_novalnet_cc_shopping_type');
+ if($this->config->get('payment_novalnet_cc_shopping_type')=='ONE_CLICK' && $this->config->get('payment_novalnet_cc_3d_enable') != 'yes'){
+ $customer_one_click=$this->request->request['customer_oneclick'];
+ }else{
+ $customer_one_click=$this->request->request['customer_oneclick'] = 'False';
+ }
+ if (!empty($this->json['error'])) {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_cc');
+
+ // Build one click form parameters.
+ $parameters = $this->model_extension_payment_novalnet->formOneClickParams($parameters, 'novalnet_cc', $shopping_type,$customer_one_click);
+
+ // Build zero amount booking parameters.
+ $parameters = $this->model_extension_payment_novalnet->zeroBookingParams($parameters, $shopping_type, 'novalnet_cc');
+
+ // Check for on-hold transaction.
+ $parameters = $this->model_extension_payment_novalnet->getOnholdParameter($parameters, $parameters['amount'], 'payment_novalnet_cc');
+ if(empty($parameters['payment_ref'])) {
+ // Validate payment details.
+ $this->json['error'] = $this->model_extension_payment_novalnet->validatePaymentFields(array(
+ 'cc_panhash',
+ 'cc_unique_id',
+ ), 'novalnet_cc');
+
+ if (!empty($this->json['error'])) {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ $parameters['pan_hash'] = $this->request->request['cc_panhash'];
+ $parameters['unique_id'] = $this->request->request['cc_unique_id'];
+ $parameters['do_redirect'] = $this->request->request['cc_do_redirect'];
+
+ } else {
+ $this->session->data['novalnet_cc_reference_tid'] = $parameters['payment_ref'];
+ }
+
+ // Check for 3D secure transaction.
+ if($this->config->get('payment_novalnet_cc_3d_enable') == 'yes' && $parameters['do_redirect'] == 1) {
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_cc');
+ $parameters['enforce_3d'] = 1;
+
+ unset($parameters['user_variable_0']);
+ // Form hidden values.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('pci_payport'), $parameters, 'novalnet_cc');
+ echo json_encode($this->json);
+ exit();
+ }
+ $parameters['nn_it'] = 'iframe';
+
+ // Perform Novalnet payment request.
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+
+ if($this->model_extension_payment_novalnet->checkResponseStatus($server_response)) {
+ $server_response['additional_details'] = $server_response['one_click_details'] = $server_response['create_payment_ref'] = '';
+
+ if (empty($parameters['payment_ref']) && ($this->config->get('payment_novalnet_cc_shopping_type') == 'ONE_CLICK'&& $this->request->request['customer_oneclick']=='True')) {
+
+ $server_response['additional_details'] = json_encode(array(
+ 'cc_holder' => $server_response['cc_holder'],
+ 'cc_card_type' => $server_response['cc_card_type'],
+ 'cc_no' => $server_response['cc_no'],
+ 'cc_exp_year' => $server_response['cc_exp_year'],
+ 'cc_exp_month' => $server_response['cc_exp_month'],
+ 'pan_hash' => $this->request->request['cc_panhash'],
+ 'unique_id' => $this->request->request['cc_unique_id'],
+ ));
+ $server_response['one_click_details'] = json_encode(array(
+ 'parent_tid' => $server_response['tid'],
+ ));
+ $server_response['create_payment_ref'] = 1;
+ }
+
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, 'novalnet_cc');
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->json['success'] = $this->url->link('checkout/success');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback() {
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get CC details
+ *
+ * @param none
+ * @return none
+ */
+ public function ccDetails($data) {
+
+
+ // Get order details.
+ if(empty($order_info)) {
+ $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
+ }
+ $language = $this->model_extension_payment_novalnet->getLanguageCode($order_info['language_code']);
+
+ $first_name = trim($order_info['payment_firstname']);
+ $last_name = trim($order_info['payment_lastname']);
+
+ // Check for first name and lastname
+ if (in_array('', array($first_name, $last_name))) {
+ $name = $first_name . $last_name;
+ list($first_name, $last_name) = (preg_match('/\s/', $name)) ? explode(' ', $name, 2) : array($name, $name);
+ }
+
+ $shopping_type = $this->config->get('payment_novalnet_cc_shopping_type');
+
+ $data['nn_client_key'] = $this->config->get('payment_novalnet_client_key');
+ $data['nn_first_name'] = $first_name;
+ $data['nn_last_name'] = $last_name;
+ $data['nn_email'] = trim($order_info['email']);
+ $data['nn_billing_street'] = (!empty($order_info['payment_address_2'])) ? $order_info['payment_address_1'] . ', ' . $order_info['payment_address_2'] : $order_info['payment_address_1'];
+ $data['nn_billing_city'] = $order_info['payment_city'];
+ $data['nn_billing_zip'] = $order_info['payment_postcode'];
+ $data['nn_billing_country_code'] = $order_info['payment_iso_code_2'];
+
+ $data['shop_currency'] = $order_info['currency_code'];
+
+ $payment_amount = $this->model_extension_payment_novalnet->getAmountFormat($order_info['total'], $order_info['currency_value']);
+
+ if ($shopping_type == 'ZERO_AMOUNT') {
+
+ $payment_amount = 0;
+
+ }
+ $data['transaction_amount'] = $payment_amount;
+ $data['nn_test_mode'] = ($this->config->get('payment_novalnet_cc_testmode'));
+ $data['nn_enforce_3d'] = ($this->config->get('payment_novalnet_cc_3d_enable') == 'yes') ? 1 : 0;
+ $data['shop_lang'] = $language;
+
+
+
+
+ // Assign description Based on 3d secure enable.
+ $data['payment_description'] = $this->language->get('text_direct_payment_description');
+ if($this->config->get('payment_novalnet_cc_3d_enable') == 'yes') {
+ $data['one_click_process_enabled'] = false;
+ $data['new_details_style'] = 'display:block';
+ $data['payment_description'] = $this->language->get('text_payment_description') . ' ' . $this->language->get('text_browser_description');
+ }
+
+ $data['shopping_type'] = $shopping_type;
+ return $data;
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getIframeStyleContent($data) {
+
+ foreach(array(
+ 'cc_iframe_standard_label',
+ 'cc_iframe_standard_input',
+ 'cc_iframe_standard_css_text',
+ ) as $v ){
+ $data[$v] = $this->config->get('payment_novalnet_' . $v);
+ }
+ return $data;
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_cc_card_name',
+ 'text_cc_date_placeholder',
+ 'text_cc_cvc_placeholder',
+ 'novalnet_cc_payment_details_error',
+ 'text_payment_description',
+ 'text_direct_payment_description',
+ 'text_test_mode_description',
+ 'zero_amount_desc',
+ 'text_cc_holder',
+ 'text_cc_cvc_hint',
+ 'text_cc_number',
+ 'text_cc_expiry_date',
+ 'text_cc_cvc',
+ 'button_confirm',
+ 'text_title',
+ 'novalnet_cc_new_card_details',
+ 'novalnet_cc_given_card_details',
+ 'text_cc_type',
+ 'text_browser_description',
+ 'save_card_details',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_eps.php b/catalog/controller/extension/payment/novalnet_eps.php
new file mode 100644
index 0000000..5c203be
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_eps.php
@@ -0,0 +1,119 @@
+language->load('extension/payment/novalnet_eps');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_eps');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_eps', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_eps');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters($this->payment_method);
+
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_eps');
+
+ // Redirect to Novalnet server.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('giropay'), $parameters, $this->payment_method);
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback() {
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_giropay.php b/catalog/controller/extension/payment/novalnet_giropay.php
new file mode 100644
index 0000000..4b86654
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_giropay.php
@@ -0,0 +1,120 @@
+language->load('extension/payment/novalnet_giropay');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_giropay');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_giropay', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_giropay');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_giropay');
+
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_giropay');
+
+ // Redirect to Third party url along with Novalnet Ideal parameters.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('giropay'), $parameters, 'novalnet_giropay');
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback() {
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_ideal.php b/catalog/controller/extension/payment/novalnet_ideal.php
new file mode 100644
index 0000000..2430e7e
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_ideal.php
@@ -0,0 +1,119 @@
+language->load('extension/payment/novalnet_ideal');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_ideal');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_ideal', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_ideal');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_ideal');
+
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_ideal');
+
+ // Redirect to Third party url along with Novalnet Ideal parameters.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('online_transfer'), $parameters, 'novalnet_ideal');
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback() {
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_instant_bank_transfer.php b/catalog/controller/extension/payment/novalnet_instant_bank_transfer.php
new file mode 100644
index 0000000..f707efc
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_instant_bank_transfer.php
@@ -0,0 +1,119 @@
+language->load('extension/payment/novalnet_instant_bank_transfer');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_instant_bank_transfer');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_instant_bank_transfer', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_instant_bank_transfer');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters($this->payment_method);
+
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, $this->payment_method);
+
+ // Redirect to Third party url along with Novalnet Instant Bank Transfer parameters.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('online_transfer'), $parameters, $this->payment_method);
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback(){
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/novalnet_instant_bank_transfer');
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_invoice.php b/catalog/controller/extension/payment/novalnet_invoice.php
new file mode 100644
index 0000000..41b946a
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_invoice.php
@@ -0,0 +1,156 @@
+language->load('extension/payment/novalnet_invoice');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ $this->load->model('checkout/order');
+
+ // Get order details.
+ $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_invoice');
+
+ // Get Guarantee details.
+ $data = $this->model_extension_payment_novalnet->getGuaranteeDetails('payment_novalnet_invoice', $order_info, $data);
+
+ $data['company'] = !empty($order_info['payment_company']) ? trim($order_info['payment_company']) : '';
+
+ // Add Language content.
+ $data = $this->getLanguageContent($data);
+
+ $data = array_map('trim', $data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_invoice', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_invoice');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ $this->json['error'] = '';
+
+ if(!empty($this->session->data['novalnet_invoice_max_time'])){
+ $this->json['error'] = $this->session->data['novalnet_invoice_status_text'];
+ }
+ // Validate for guarantee process.
+ $this->json['error'] = empty($this->json['error']) ? $this->model_extension_payment_novalnet->validateGuaranteeProcess('novalnet_invoice') : $this->json['error'];
+
+ if (!empty($this->json['error'])) {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_invoice');
+
+ // Form guarantee payment parameters.
+ $parameters = $this->model_extension_payment_novalnet->formGuaranteePaymentParams($parameters, 'payment_novalnet_invoice');
+
+ // Check for on-hold transaction.
+ $parameters = $this->model_extension_payment_novalnet->getOnholdParameter($parameters, $parameters['amount'], 'payment_novalnet_invoice');
+
+ // Form payment parameters.
+ $parameters['invoice_type'] = 'INVOICE';
+ $parameters['invoice_ref'] = 'BNR-' . $parameters['product'] . '-' . $parameters['order_no'];
+
+ // Form due date.
+ $invoice_duedate = trim($this->config->get('payment_novalnet_invoice_due_date'));
+ if (!empty($invoice_duedate)) {
+ $parameters['due_date'] = date('Y-m-d', mktime(0, 0, 0, date('m'), (date('d') + $invoice_duedate), date('Y')));
+ }
+ // Perform payment call.
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+ if(!empty($server_response['status']) && $server_response['status'] == '100') {
+ $server_response['additional_details'] = json_encode(array(
+ 'due_date' => isset($server_response['due_date']) ? $server_response['due_date'] : '',
+ 'invoice_iban' => $server_response['invoice_iban'],
+ 'invoice_bic' => $server_response['invoice_bic'],
+ 'invoice_bankname' => $server_response['invoice_bankname'],
+ 'invoice_bankplace' => $server_response['invoice_bankplace'],
+ ));
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ // Generate Novalnet comments.
+ if($server_response['tid_status'] != 75) {
+ $data['novalnet_comments'] .= $this->model_extension_payment_novalnet->prepareNovalnetComments($server_response, $data['order_info']);
+ }
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->model_extension_payment_novalnet->unsetSessionValues('payment_novalnet_invoice');
+ $this->json['success'] = $this->url->link('checkout/success');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_guarantee_payment_dob',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_online_bank_transfer.php b/catalog/controller/extension/payment/novalnet_online_bank_transfer.php
new file mode 100644
index 0000000..1f95f95
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_online_bank_transfer.php
@@ -0,0 +1,118 @@
+language->load('extension/payment/novalnet_online_bank_transfer');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_online_bank_transfer');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_online_bank_transfer', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_online_bank_transfer');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters($this->payment_method);
+
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, $this->payment_method);
+ // Redirect to Third party url along with Novalnet Instant Bank Transfer parameters.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('online_bank_transfer'), $parameters, $this->payment_method);
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback(){
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/novalnet_online_bank_transfer');
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_paypal.php b/catalog/controller/extension/payment/novalnet_paypal.php
new file mode 100644
index 0000000..5b8201c
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_paypal.php
@@ -0,0 +1,174 @@
+language->load('extension/payment/novalnet_paypal');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_paypal');
+
+ // Get one click shopping details.
+
+ $data = $this->model_extension_payment_novalnet->getShoppingTypeDetails('novalnet_paypal',
+ $data);
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ $data['oneclick']=$this->config->get('payment_novalnet_paypal_shopping_type');
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_paypal', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_paypal');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ $shopping_type = $this->config->get('payment_novalnet_paypal_shopping_type');
+
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_paypal');
+
+ // Build one click form parameters.
+ if($this->config->get('payment_novalnet_paypal_shopping_type')=='ONE_CLICK'){
+ $customer_one_click=$this->request->request['customer_oneclick'];
+
+ }else{
+ $customer_one_click=$this->request->request['customer_oneclick']='False';
+ }
+ $parameters = $this->model_extension_payment_novalnet->formOneClickParams($parameters, 'novalnet_paypal', $shopping_type,$customer_one_click);
+
+ $parameters = $this->model_extension_payment_novalnet->zeroBookingParams($parameters, $shopping_type, 'novalnet_paypal');
+
+
+ if($shopping_type != 'ZERO_AMOUNT'){
+ $parameters = $this->model_extension_payment_novalnet->getOnholdParameter($parameters, $parameters['amount'], 'payment_novalnet_paypal');
+ }
+
+ if(($shopping_type != 'ONE_CLICK' && $this->request->request['customer_oneclick']!='True') || ( $shopping_type == 'ONE_CLICK' && !empty($parameters['create_payment_ref']))||$this->request->request['customer_oneclick']=='False') {
+ // Build Third party parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_paypal');
+
+ // Redirect to Novalnet server.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('paypal'), $parameters, 'novalnet_paypal');
+ echo json_encode($this->json);
+ exit();
+ } elseif($this->request->request['customer_oneclick']=='True') {
+ $this->session->data['novalnet_paypal_reference_tid'] = $parameters['payment_ref'];
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+
+ if(!empty($server_response['status']) && $server_response['status'] == '100') {
+ $server_response['additional_details'] = $server_response['one_click_details'] = $server_response['create_payment_ref'] = '';
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, 'novalnet_paypal');
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->json['success'] = $this->url->link('checkout/success');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ }
+
+ public function callback() {
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+
+ // Check and store one click process informations.
+ if (!empty($server_response['create_payment_ref']) && ($this->config->get('payment_novalnet_paypal_shopping_type') == 'ONE_CLICK')) {
+ $server_response['additional_details'] = json_encode(array(
+ 'paypal_transaction_id' => $server_response['paypal_transaction_id'],
+ 'tid' => $server_response['tid'],
+ ));
+ $server_response['one_click_details'] = json_encode(array(
+ 'parent_tid' => $server_response['tid'],
+ ));
+ }
+
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'novalnet_paypal_new_payment_details',
+ 'novalnet_paypal_placed_payment_details',
+ 'novalnet_paypal_transaction_id',
+ 'zero_amount_desc',
+ 'novalnet_paypal_novalnet_tid',
+ 'text_guarantee_payment_reference_transaction',
+ 'text_title',
+ 'save_card_details',
+ 'text_order_processed',
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_prepayment.php b/catalog/controller/extension/payment/novalnet_prepayment.php
new file mode 100644
index 0000000..59df603
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_prepayment.php
@@ -0,0 +1,121 @@
+language->load('extension/payment/novalnet_prepayment');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_prepayment');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_prepayment', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_prepayment');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_prepayment');
+
+ // Form payment parameters.
+ $parameters['invoice_type'] = 'PREPAYMENT';
+ $parameters['invoice_ref'] = 'BNR-' . $parameters['product'] . '-' . $parameters['order_no'];
+
+ // Form due date.
+ $prepayment_duedate = trim($this->config->get('payment_novalnet_prepayment_due_date'));
+ if (!empty($prepayment_duedate)) {
+ $parameters['due_date'] = date('Y-m-d', mktime(0, 0, 0, date('m'), (date('d') + $prepayment_duedate), date('Y')));
+ }
+
+ // Perform payment call.
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+
+ // Validate paygate response.
+ if($this->model_extension_payment_novalnet->checkResponseStatus($server_response)) {
+ $server_response['additional_details'] = json_encode(array(
+ 'due_date' => $server_response['due_date'],
+ 'invoice_iban' => $server_response['invoice_iban'],
+ 'invoice_bic' => $server_response['invoice_bic'],
+ 'invoice_bankname' => $server_response['invoice_bankname'],
+ 'invoice_bankplace' => $server_response['invoice_bankplace'],
+ ));
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, 'novalnet_prepayment');
+
+ // Generate Novalnet comments.
+ $data['novalnet_comments'] .= $this->model_extension_payment_novalnet->prepareNovalnetComments($server_response, $data['order_info']);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->json['success'] = $this->url->link('checkout/success');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed',
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_przelewy24.php b/catalog/controller/extension/payment/novalnet_przelewy24.php
new file mode 100644
index 0000000..b266c7f
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_przelewy24.php
@@ -0,0 +1,119 @@
+language->load('extension/payment/novalnet_przelewy24');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_przelewy24');
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_przelewy24', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_przelewy24');
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_przelewy24');
+
+ // Build Redirect parameters.
+ $parameters = $this->model_extension_payment_novalnet->getRedirectParameters($parameters, 'novalnet_przelewy24');
+
+ // Redirect to Novalnet server.
+ $this->json = $this->model_extension_payment_novalnet->performRedirectProcess($this->model_extension_payment_novalnet->getUrl('przelewy24'), $parameters, 'novalnet_przelewy24');
+ echo json_encode($this->json);
+ exit();
+ }
+
+ /**
+ * Get server response details
+ *
+ * @param none
+ * @return none
+ */
+ public function callback() {
+
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ $this->language->load('extension/payment/' . $this->payment_method);
+ $server_response = $this->model_extension_payment_novalnet->checkRedirectPaymentProcess($this->payment_method);
+ if (!empty($server_response['type']) && $server_response['type'] == 'failure') {
+ $this->session->data['error'] = $server_response['error'];
+ $this->response->redirect($this->url->link('checkout/checkout'));
+ } else {
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, $this->payment_method);
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->response->redirect($this->url->link('checkout/success'));
+ }
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_browser_description',
+ 'button_confirm',
+ 'text_title',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/payment/novalnet_sepa.php b/catalog/controller/extension/payment/novalnet_sepa.php
new file mode 100644
index 0000000..e3657da
--- /dev/null
+++ b/catalog/controller/extension/payment/novalnet_sepa.php
@@ -0,0 +1,202 @@
+language->load('extension/payment/novalnet_sepa');
+
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ $this->load->model('checkout/order');
+
+ // Load Order information.
+ $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
+
+ // Assign basic details.
+ $data = $this->model_extension_payment_novalnet->getBasicDetails('payment_novalnet_sepa');
+
+ // Get one click shopping details.
+ $data = $this->model_extension_payment_novalnet->getShoppingTypeDetails('novalnet_sepa', $data);
+
+ // Get Guarantee details.
+ $data = $this->model_extension_payment_novalnet->getGuaranteeDetails('payment_novalnet_sepa', $order_info, $data);
+
+ // Add Direct Debit SEPA additional details.
+ $data = $this->sepaDetails($data, $order_info);
+
+ // Add language content.
+ $data = $this->getLanguageContent($data);
+
+ // one_click customer_verification
+ $data['one_click']=$this->config->get('payment_novalnet_sepa_shopping_type');
+
+ // Add template.
+ return $this->load->view('extension/payment/novalnet_sepa', $data);
+ }
+
+ /**
+ * Perform order confirmation process
+ *
+ * @param none
+ * @return none
+ */
+ public function confirm()
+ {
+ // Load language.
+ $this->language->load('extension/payment/novalnet_sepa');
+ // Load model.
+ $this->load->model('checkout/order');
+ $this->load->model('extension/payment/novalnet');
+ // Get shopping type value.
+ $shopping_type = $this->config->get('payment_novalnet_sepa_shopping_type');
+ $this->json['error'] = '';
+ if(!empty($this->session->data['novalnet_sepa_max_time'])){
+ $this->json['error'] = $this->session->data['novalnet_sepa_status_text'];
+ }
+ // Validate for guarantee process.
+ $this->json['error'] = empty($this->json['error']) ? $this->model_extension_payment_novalnet->validateGuaranteeProcess('novalnet_sepa') : $this->json['error'];
+ // Proceed validation process.
+ if (!empty($this->json['error'])) {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ // Build Basic parameters.
+ $parameters = $this->model_extension_payment_novalnet->getParameters('novalnet_sepa');
+ $parameters['iban']=$this->request->request['novalnet_sepa_account_no'];
+ // Build one click form parameters.
+ if($this->config->get('payment_novalnet_sepa_shopping_type')=='ONE_CLICK') {
+ $customer_one_click=$this->request->request['customer_oneclick'];
+ } else {
+ $customer_one_click=$this->request->request['customer_oneclick']='False';
+ }
+ $parameters = $this->model_extension_payment_novalnet->formOneClickParams($parameters, 'novalnet_sepa', $shopping_type,$customer_one_click);
+ // Form guarantee payment parameters.
+ $parameters = $this->model_extension_payment_novalnet->formGuaranteePaymentParams($parameters, 'payment_novalnet_sepa');
+ // Build zero amount booking parameters.
+ if($parameters['key'] == '37'){
+ $parameters = $this->model_extension_payment_novalnet->zeroBookingParams($parameters, $shopping_type, 'novalnet_sepa');
+ }
+ // Check for on-hold transaction.
+ $parameters = $this->model_extension_payment_novalnet->getOnholdParameter($parameters, $parameters['amount'], 'payment_novalnet_sepa');
+
+ // Form due date.
+ $sepa_due_date = !empty($this->config->get('payment_novalnet_sepa_due_date')) ? (trim($this->config->get('payment_novalnet_sepa_due_date'))) : '';
+ if(!empty($sepa_due_date))
+ $parameters['sepa_due_date'] = date('Y-m-d', mktime(0, 0, 0, date('m'), (date('d') + $sepa_due_date), date('Y')));
+
+ if(empty($parameters['payment_ref'])) {
+ $required_param = array('novalnet_sepa_holder');
+ if($shopping_type = 'ONE_CLICK' && $this->request->request['novalnet_sepa_one_click_shopping'] != '1'){
+ $required_param = array('novalnet_sepa_holder');
+ }
+ $this->json['error'] = $this->model_extension_payment_novalnet->validatePaymentFields($required_param, 'novalnet_sepa');
+ if (!empty($this->json['error'])) {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+ $parameters['bank_account_holder'] = trim($this->request->request['novalnet_sepa_holder']);
+ } else {
+ $this->session->data['novalnet_sepa_reference_tid'] = $parameters['payment_ref'];
+ }
+ // Perform payment call.
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($parameters);
+ // Check for valid response.
+ if($this->model_extension_payment_novalnet->checkResponseStatus($server_response)) {
+ $server_response['additional_details'] = $server_response['one_click_details'] = $server_response['create_payment_ref'] = '';
+ // Check and store one click process informations.
+ if($this->config->get('payment_novalnet_sepa_shopping_type') == 'ONE_CLICK') {
+ if (empty($parameters['payment_ref']) && $this->request->request['customer_oneclick']=='True') {
+ $server_response['additional_details'] = json_encode(array(
+ 'account_holder' => $server_response['bankaccount_holder'],
+ 'iban' => $server_response['iban'],
+ ));
+ $server_response['one_click_details'] = json_encode(array(
+ 'parent_tid' => $server_response['tid'],
+ ));
+ $server_response['create_payment_ref'] = 1;
+ }
+ }
+ $data = $this->model_extension_payment_novalnet->transactionSuccess($server_response, 'novalnet_sepa');
+ $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $data['orderStatus'], $this->db->escape($data['novalnet_comments']), true);
+ $this->json['success'] = $this->url->link('checkout/success');
+ $this->model_extension_payment_novalnet->unsetSessionValues('payment_novalnet_sepa');
+ } else {
+ $this->json['error'] = $this->model_extension_payment_novalnet->setResponseMessage($server_response);
+ }
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->json));
+ return false;
+ }
+
+ /**
+ * Get language content from language file.
+ *
+ * @param $data
+ * @return none
+ */
+ public function getLanguageContent($data) {
+ foreach (array(
+ 'text_payment_description',
+ 'text_test_mode_description',
+ 'text_sepa_account_holder',
+ 'text_sepa_account_no',
+ 'button_confirm',
+ 'text_title',
+ 'novalnet_sepa_payment_details_error',
+ 'novalnet_sepa_new_account_details',
+ 'novalnet_sepa_given_account_details',
+ 'text_guarantee_payment_dob',
+ 'text_order_processed'
+ ) as $value) {
+ $data[$value] = $this->language->get($value);
+ }
+ return $data;
+ }
+
+ /**
+ * Get sepa details.
+ *
+ * @param $data
+ * @param $order_info
+ * @return none
+ */
+ public function sepaDetails($data, $order_info) {
+ // Assign form default values.
+ $data['account_holder'] = $order_info['payment_firstname'] . ' ' . $order_info['payment_lastname'];
+ $data['company'] = !empty($order_info['payment_company']) ? trim($order_info['payment_company']) : '';
+ $data['remote_ip'] = $this->model_extension_payment_novalnet->getIpAddress('REMOTE_ADDR');
+ return $data;
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_cc.php b/catalog/controller/extension/recurring/novalnet_cc.php
new file mode 100644
index 0000000..c9446f9
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_cc.php
@@ -0,0 +1,59 @@
+request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+
+ $this->load->model('account/recurring');
+
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ $data['subscription_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_subscriptions', 'next_subs_cycle', 'order_recurring_id =' . $this->request->get['order_recurring_id']);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_common');
+ foreach(array('text_novalnet_TID', 'text_novalnet_order_no', 'text_novalnet_amount', 'text_transaction_details', 'text_payment_method', 'text_next_charging_date', 'text_recurring_orders', 'button_subscription_cancel', 'text_loading') as $value){
+ $data[$value] = $this->language->get($value);
+ }
+ //Get order status id from order table
+ $data['recurring_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'order_no, tid, amount, payment_type, transaction_details, status', 'order_recurring_id =' . $this->request->get['order_recurring_id'], true);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_cc');
+ $data['payment_method'] = $this->language->get('text_novalnet_cc_title');
+ $data['payment_type'] = 'novalnet_cc';
+ $data['order_recurring_id'] = $order_recurring_id;
+ $data['next_subs_cycle'] = $data['subscription_details']['next_subs_cycle'];
+ return $this->load->view('extension/recurring/novalnet_recurring', $data);
+ }
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_invoice.php b/catalog/controller/extension/recurring/novalnet_invoice.php
new file mode 100644
index 0000000..f01e9a3
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_invoice.php
@@ -0,0 +1,58 @@
+request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+ $this->load->model('account/recurring');
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ $data['subscription_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_subscriptions', 'next_subs_cycle', 'order_recurring_id =' . $this->request->get['order_recurring_id']);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_common');
+ foreach(array('text_novalnet_TID', 'text_novalnet_order_no', 'text_novalnet_amount', 'text_transaction_details', 'text_payment_method', 'text_next_charging_date', 'text_recurring_orders', 'button_subscription_cancel', 'text_loading') as $value){
+ $data[$value] = $this->language->get($value);
+ }
+ //Get order status id from order table
+ $data['recurring_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'order_no, tid, amount, payment_type, transaction_details, status', 'order_recurring_id =' . $this->request->get['order_recurring_id'], true);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_invoice');
+ $data['payment_method'] = $this->language->get('text_novalnet_invoice_title');
+ $data['payment_type'] = 'novalnet_invoice';
+ $data['order_recurring_id'] = $order_recurring_id;
+ $data['next_subs_cycle'] = $data['subscription_details']['next_subs_cycle'];
+ return $this->load->view('extension/recurring/novalnet_recurring', $data);
+ }
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_paypal.php b/catalog/controller/extension/recurring/novalnet_paypal.php
new file mode 100644
index 0000000..274558a
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_paypal.php
@@ -0,0 +1,60 @@
+request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+
+ $this->load->model('account/recurring');
+
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ $data['subscription_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_subscriptions', 'next_subs_cycle', 'order_recurring_id =' . $this->request->get['order_recurring_id']);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_common');
+ foreach(array('text_novalnet_TID', 'text_novalnet_order_no', 'text_novalnet_amount', 'text_transaction_details', 'text_payment_method', 'text_next_charging_date', 'text_recurring_orders', 'button_subscription_cancel', 'text_loading') as $value){
+ $data[$value] = $this->language->get($value);
+ }
+
+ //Get order status id from order table
+ $data['recurring_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'order_no, tid, amount, payment_type, transaction_details, status', 'order_recurring_id =' . $this->request->get['order_recurring_id'], true);
+
+ // Load language.
+ $this->load->language('extension/payment/novalnet_paypal');
+ $data['payment_method'] = $this->language->get('text_novalnet_paypal_title');
+ $data['payment_type'] = 'novalnet_paypal';
+ $data['order_recurring_id'] = $order_recurring_id;
+ $data['next_subs_cycle'] = $data['subscription_details']['next_subs_cycle'];
+ return $this->load->view('extension/recurring/novalnet_recurring', $data);
+ }
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_prepayment.php b/catalog/controller/extension/recurring/novalnet_prepayment.php
new file mode 100644
index 0000000..7af0d1c
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_prepayment.php
@@ -0,0 +1,60 @@
+request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+
+ $this->load->model('account/recurring');
+
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ $data['subscription_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_subscriptions', 'next_subs_cycle', 'order_recurring_id =' . $this->request->get['order_recurring_id']);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_common');
+ foreach(array('text_novalnet_TID', 'text_novalnet_order_no', 'text_novalnet_amount', 'text_transaction_details', 'text_payment_method', 'text_next_charging_date', 'text_recurring_orders', 'button_subscription_cancel', 'text_loading') as $value){
+ $data[$value] = $this->language->get($value);
+ }
+
+ //Get order status id from order table
+ $data['recurring_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'order_no, tid, amount, payment_type, transaction_details, status', 'order_recurring_id =' . $this->request->get['order_recurring_id'], true);
+
+ // Load language.
+ $this->load->language('extension/payment/novalnet_prepayment');
+ $data['payment_method'] = $this->language->get('text_novalnet_prepayment_title');
+ $data['payment_type'] = 'novalnet_prepayment';
+ $data['order_recurring_id'] = $order_recurring_id;
+ $data['next_subs_cycle'] = $data['subscription_details']['next_subs_cycle'];
+ return $this->load->view('extension/recurring/novalnet_recurring', $data);
+ }
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_recurring.php b/catalog/controller/extension/recurring/novalnet_recurring.php
new file mode 100644
index 0000000..6f733ac
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_recurring.php
@@ -0,0 +1,219 @@
+load->language('extension/payment/novalnet_invoice');
+
+ if (isset($this->request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+ $this->load->model('account/recurring');
+
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ $data['text_loading'] = $this->language->get('text_loading');
+
+ $data['button_continue'] = $this->language->get('button_continue');
+ $data['button_cancel'] = $this->language->get('button_cancel');
+
+ $data['continue'] = $this->url->link('account/recurring', '', true);
+
+ if ($recurring_info['status'] == 2 || $recurring_info['status'] == 3) {
+ $data['order_recurring_id'] = $order_recurring_id;
+ } else {
+ $data['order_recurring_id'] = '';
+ }
+
+ return $this->load->view('extension/recurring/novalnet_invoice', $data);
+ }
+ }
+
+ public function recurringCancel() {
+ $json = array();
+ $this->load->language('extension/payment/novalnet_common');
+ //Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_subscriptions', array(
+ 'next_subs_cycle' => "'0000-00-00'"
+ ), 'order_recurring_id=' . $this->request->request['order_recurring_id']);
+
+ $this->model_extension_payment_novalnet->dbUpdate('order_recurring', array(
+ 'status' => "'3'"
+ ), 'order_recurring_id=' . $this->request->request['order_recurring_id']);
+
+ $json['success'] = $this->language->get('text_recurring_cancel');
+
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($json));
+ }
+
+ /**
+ * Execution of Novalnet cron process
+ *
+ * @param none
+ * @return array
+ */
+ public function cronProcess() {
+ $this->load->model('extension/payment/novalnet');
+ $this->load->language('extension/payment/novalnet_common');
+ $this->load->model('account/order');
+ $this->load->model('account/recurring');
+ $this->load->model('checkout/order');
+ $recurring_profiles = $this->model_extension_payment_novalnet->getNovalnetRecurringProfiles();
+ $novalnet_response = array();
+ $next_payment_error_msg = $this->language->get('text_recurring_date_not_met');
+ if (!empty($recurring_profiles)) {
+ foreach ($recurring_profiles as $profile) {
+
+ $recurring_order = $this->model_extension_payment_novalnet->getRecurringOrder($profile['order_recurring_id']);
+ $recurring_info = $this->model_extension_payment_novalnet->getRecuringOrders($profile['order_recurring_id']);
+ $recurring_order['trial_details'] = json_decode($recurring_order['trial_details'], true);
+ $next_payment = new DateTime($recurring_order['next_subs_cycle']);
+ $today = new DateTime('now');
+
+ $recurring_order['recurring_details'] = json_decode($recurring_order['recurring_details'], true);
+ $proceed_payment = false;
+ if(!empty($recurring_order['trial_details']['trial_duration']) && $recurring_order['trial_details']['trial_duration'] > $recurring_info->num_rows) {
+ $proceed_payment = true;
+ $amount = $recurring_order['trial_details']['trial_price'];
+ $next_payment = $this->model_extension_payment_novalnet->calculateSubscriptionSchedule($recurring_order['trial_details']['trial_frequency'], $next_payment, $recurring_order['trial_details']['trial_cycle']);
+
+ } else if(isset($recurring_order['recurring_details']['recurring_duration'])) {
+ $total_length = !empty($recurring_order['trial_details']['trial_duration']) ? (int)$recurring_order['trial_details']['trial_duration'] + (int)$recurring_order['recurring_details']['recurring_duration'] : $recurring_order['recurring_details']['recurring_duration'];
+ if($total_length > $recurring_info->num_rows || ($recurring_order['recurring_details']['recurring_duration'] == 0 && $total_length <= $recurring_info->num_rows)) {
+ $proceed_payment = true;
+ $amount = $recurring_order['recurring_details']['recurring_price'];
+ $next_payment = $this->model_extension_payment_novalnet->calculateSubscriptionSchedule($recurring_order['recurring_details']['recurring_frequency'], $next_payment, $recurring_order['recurring_details']['recurring_cycle']);
+ }
+ } else{
+ continue;
+ }
+ $order_info = $this->model_checkout_order->getOrder($profile['order_id']);
+
+ // Check and process payment
+ if($proceed_payment) {
+ $data = $this->model_extension_payment_novalnet->getParameters($order_info['payment_code'], $order_info);
+ $reference_details = $this->model_extension_payment_novalnet->getReferenceDetails($profile['order_id']);
+ $reference_details = !empty($reference_details['transaction_details']) ? json_decode($reference_details['transaction_details'], true) : '';
+
+ $data['amount'] = round($amount * $order_info['currency_value']);
+ unset($data['order_no']);
+ if(in_array($order_info['payment_code'], array('novalnet_invoice', 'novalnet_prepayment'))) {
+ $data['invoice_type'] = $data['payment_type'];
+ if($order_info['payment_code'] == 'novalnet_invoice'){
+ $invoice_duedate = trim($this->config->get('novalnet_invoice_due_date'));
+ if (!empty($invoice_duedate)) {
+ $data['due_date'] = date('Y-m-d', mktime(0, 0, 0, date('m'), (date('d') + $invoice_duedate), date('Y')));
+ }
+ }
+ } else {
+ $data['payment_ref'] = (!empty($reference_details['reference_tid']) && $reference_details['reference_tid'] != 'NULL') ? $reference_details['reference_tid'] : $recurring_order['tid'];
+ }
+ $this->log->write($this->language->get('text_recurring_request_parameters') . ' -> ' . json_encode($data));
+ $server_response = $this->model_extension_payment_novalnet->performPaymentCall($data);
+ if (!empty($server_response['status']) && in_array($server_response['status'], array('100', '90'))) {
+ $novalnet_response[$profile['order_recurring_id']] = $server_response;
+ $this->log->write($this->language->get('text_recurring_response_parameters') . ' -> ' . json_encode($novalnet_response[$profile['order_recurring_id']]));
+ $update_subscription_details = array(
+ 'next_subs_cycle' => "'" . date_format($next_payment, 'Y-m-d') . "'",
+ 'recurring_date_added' => "'" . date_format($today, 'Y-m-d') . "'",
+ );
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_subscriptions', $update_subscription_details, 'order_recurring_id=' . $profile['order_recurring_id']);
+ $this->load->language('extension/payment/' . $order_info['payment_code']);
+
+ // Prepare transaction comments.
+ $transaction_comments = $this->model_extension_payment_novalnet->prepareTransactionComments($server_response, $order_info['payment_code']);
+ $formated_amount = $this->currency->format(($data['amount']/100), $order_info['currency_code'], '1');
+
+ // Get callback amount.
+ $callback_amount = (in_array($order_info['payment_code'], array('novalnet_invoice', 'novalnet_prepayment')) || ($order_info['payment_code'] == 'novalnet_paypal' && $server_response['tid_status'] == '90')) ? 0 : $amount;
+
+ $paid_status = 'paid';
+ if(in_array($data['key'], array('27', '41'))) {
+ $order_info['total'] = ($amount/100);
+ $order_info['currency'] = $data['currency'];
+ $transaction_comments .= $this->model_extension_payment_novalnet->prepareBankDetailsComments($server_response, $order_info);
+ $paid_status = 'unpaid';
+ } else if ($server_response['status'] == '90') {
+ $paid_status = 'unpaid';
+ }
+ $this->db->query("INSERT INTO " . DB_PREFIX . "order_recurring_transaction SET order_recurring_id = '" . (int)$recurring_order['order_recurring_id'] . "', reference='" . $server_response['tid'] . "', date_added = NOW(), amount = '" . (float) ($amount/100) . "', type = '1'");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "novalnet_recurring_transactions SET order_no = '" . $recurring_order['order_no'] . "', order_recurring_id=" . $recurring_order['order_recurring_id'] . ", tid='" . $server_response['tid'] . "', amount = '" . $formated_amount . "', payment_type='" . $order_info['payment_code'] . "', transaction_details='" . $transaction_comments . "', status='" . $paid_status . "', date_added = NOW()");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "novalnet_merchant_script SET order_no = '" . $recurring_order['order_no'] . "', original_tid=" . $server_response['tid'] . ", callback_tid='" . $server_response['tid'] . "', payment_type='" . $order_info['payment_code'] . "', amount = '" . $callback_amount . "', date = '" . date('Y-m-d H:i:s') . "'");
+ $additional_details = '';
+ if(in_array($order_info['payment_code'], array('novalnet_invoice', 'novalnet_prepayment'))) {
+ $additional_details = addslashes(json_encode(array(
+ 'due_date' => $server_response['due_date'],
+ 'invoice_iban' => $server_response['invoice_iban'],
+ 'invoice_bic' => $server_response['invoice_bic'],
+ 'invoice_bankname' => $server_response['invoice_bankname'],
+ 'invoice_bankplace' => $server_response['invoice_bankplace'],
+ )));
+ }
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "novalnet_transactions SET order_no = '" . $recurring_order['order_no'] . "', tid=" . $server_response['tid'] . ", gateway_status='" . $server_response['tid_status'] . "', payment_type='" . $order_info['payment_code'] . "', payment_id=" . $data['key'] . ", customer_id = " . $order_info['customer_id'] . ", create_payment_ref = '', payment_configurations = '" . json_encode(array(
+ 'vendor' => $data['vendor'],
+ 'product' => $data['product'],
+ 'tariff' => $data['tariff'],
+ 'auth_code' => $data['auth_code'],
+ 'test_mode' => $data['test_mode'],
+ )) . "', transaction_details = '" . json_encode(array(
+ 'amount' => $data['amount'],
+ 'total_amount' => $data['amount'],
+ 'refund_amount' => 0,
+ 'currency' => $order_info['currency_code'],
+ 'reference_tid' => !empty($data['payment_ref']) ? $data['payment_ref'] : '',
+ )) . "', additional_details='" . $additional_details . "', date = '" . date('Y-m-d H:i:s') . "'");
+ $order_status_id = trim($this->config->get('payment_'.$order_info['payment_code'].'_order_completion_status'));
+ $this->model_checkout_order->addOrderHistory($profile['order_id'], $order_status_id, trim($transaction_comments), true);
+ } else {
+ $novalnet_response[$profile['order_recurring_id']] = (!empty($server_response['status_desc'])) ? $server_response['status_desc'] : (!empty($server_response['status_text']) ? $server_response['status_text'] : $this->language->get('error_payment_not_successful'));
+ $this->log->write($novalnet_response[$profile['order_recurring_id']]);
+ }
+ } else {
+ $novalnet_response[$profile['order_recurring_id']] = $this->language->get('text_recurring_profile_canceled');
+ $this->log->write($novalnet_response[$profile['order_recurring_id']]);
+ $this->model_extension_payment_novalnet->dbUpdate('novalnet_subscriptions', array(
+ 'next_subs_cycle' => "'0000-00-00'"
+ ), 'order_recurring_id=' . $profile['order_recurring_id']);
+ $this->model_extension_payment_novalnet->dbUpdate('order_recurring', array(
+ 'status' => "'5'"
+ ), 'order_id=' . $order_info['order_id']);
+ }
+ }
+ }
+ echo "Cron response";
+ $this->log->write(json_encode(((!empty($novalnet_response)) ? $novalnet_response : $next_payment_error_msg)));
+ print_r((!empty($novalnet_response)) ? $novalnet_response : $next_payment_error_msg);
+ }
+}
diff --git a/catalog/controller/extension/recurring/novalnet_sepa.php b/catalog/controller/extension/recurring/novalnet_sepa.php
new file mode 100644
index 0000000..69765f6
--- /dev/null
+++ b/catalog/controller/extension/recurring/novalnet_sepa.php
@@ -0,0 +1,59 @@
+request->get['order_recurring_id'])) {
+ $order_recurring_id = $this->request->get['order_recurring_id'];
+ } else {
+ $order_recurring_id = 0;
+ }
+
+ $this->load->model('account/recurring');
+
+ $recurring_info = $this->model_account_recurring->getOrderRecurring($order_recurring_id);
+
+ if ($recurring_info) {
+ // Load Novalnet model.
+ $this->load->model('extension/payment/novalnet');
+ $data['subscription_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_subscriptions', 'next_subs_cycle', 'order_recurring_id =' . $this->request->get['order_recurring_id']);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_common');
+ foreach(array('text_novalnet_TID', 'text_novalnet_order_no', 'text_novalnet_amount', 'text_transaction_details', 'text_payment_method', 'text_next_charging_date', 'text_recurring_orders', 'button_subscription_cancel', 'text_loading') as $value){
+ $data[$value] = $this->language->get($value);
+ }
+ //Get order status id from order table
+ $data['recurring_details'] = $this->model_extension_payment_novalnet->dbSelect('novalnet_recurring_transactions', 'order_no, tid, amount, payment_type, transaction_details, status', 'order_recurring_id =' . $this->request->get['order_recurring_id'], true);
+ // Load language.
+ $this->load->language('extension/payment/novalnet_sepa');
+ $data['payment_method'] = $this->language->get('text_novalnet_sepa_title');
+ $data['payment_type'] = 'novalnet_sepa';
+ $data['order_recurring_id'] = $order_recurring_id;
+ $data['next_subs_cycle'] = $data['subscription_details']['next_subs_cycle'];
+ return $this->load->view('extension/recurring/novalnet_recurring', $data);
+ }
+ }
+}
diff --git a/catalog/language/de-de/callback/vendorScript.php b/catalog/language/de-de/callback/vendorScript.php
new file mode 100644
index 0000000..d709e31
--- /dev/null
+++ b/catalog/language/de-de/callback/vendorScript.php
@@ -0,0 +1,49 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_cc.php b/catalog/language/de-de/extension/payment/novalnet_cc.php
new file mode 100644
index 0000000..4ed6de3
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_cc.php
@@ -0,0 +1,39 @@
+';
+$_['payment_logo'] = ' ';
+$_['amex_logo'] = ' ';
+$_['save_card_details'] = 'Meine Kartendaten für zukünftige Bestellungen speichern';
diff --git a/catalog/language/de-de/extension/payment/novalnet_common.php b/catalog/language/de-de/extension/payment/novalnet_common.php
new file mode 100644
index 0000000..db7e023
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_common.php
@@ -0,0 +1,76 @@
+Die Zahlung wird im Testmodus durchgeführt, daher wird der Betrag für diese Transaktion nicht eingezogen.';
+$_['text_novalnet_TID'] = 'Novalnet Transaktions-ID: ';
+$_['text_novalnet_test_order'] = 'Testbestellung';
+$_['text_novalnet_automaticredirection'] = 'Nach der erfolgreichen Überprüfung werden Sie auf die abgesicherte Novalnet-Bestellseite umgeleitet, um die Zahlung fortzusetzen.';
+$_['text_wait'] = 'Please wait...';
+$_['text_order_processed'] = 'Warten Sie bitte, Ihre Bestellung wird vearbeitet.';
+$_['error_check_hash'] = 'Während der Umleitung wurden einige Daten geändert. Die Überprüfung des Hashes schlug fehl';
+$_['text_redirect'] = 'Sie werden zum Shop weitergeleitet. Bitte warten Sie.';
+$_['text_browser_description'] = 'Bitte schließen Sie den Browser nach der erfolgreichen Zahlung nicht, bis Sie zum Shop zurückgeleitet wurden.';
+$_['text_payment_description'] = 'Nach der erfolgreichen Überprüfung werden Sie auf die abgesicherte Novalnet-Bestellseite umgeleitet, um die Zahlung fortzusetzen.';
+$_['text_barzahlen_payment_description'] = 'Nach erfolgreichem Bestellabschluss erhalten Sie einen Zahlschein bzw. eine SMS. Damit können Sie Ihre Online-Bestellung bei einem unserer Partner im Einzelhandel (z.B. Drogerie, Supermarkt etc.)';
+$_['error_order_amount_changed'] = 'Der Bestellbetrag hat sich geändert, setzen Sie bitte die neue Bestellung fort.';
+$_['text_guarantee_payment_dob'] = 'Ihr Geburtsdatum';
+$_['error_dob_empty'] = 'Geben Sie bitte Ihr Geburtsdatum ein';
+$_['error_dob_invalid_format'] = 'Ungültiges Datumsformat';
+$_['error_sepa_age_below_18'] = 'Sie müssen mindestens 18 Jahre alt sein.';
+$_['error_guarantee_billing_shipping_address'] = 'Rechnungsadresse und Lieferadresse müssen übereinstimmen ';
+$_['error_guarantee_currency'] = 'Als Währung ist nur EUR erlaubt ';
+$_['error_guarantee_minimum_amount'] = 'Der Mindestbestellwert beträgt ';
+$_['error_eur'] = ' EUR ';
+$_['error_guarantee_country'] = 'Als Land ist nur Deutschland, Österreich oder Schweiz erlaubt ';
+$_['error_telephone_empty'] = 'Geben Sie bitte Ihre Telefonnummer ein';
+$_['error_mobile_empty'] = 'Geben Sie bitte Ihre Mobiltelefonnummer ein';
+$_['text_payment_reference'] = 'Verwendungszweck';
+$_['text_payment_reference_any_one'] = 'Bitte verwenden Sie einen der unten angegebenen Verwendungszwecke für die Überweisung, da nur so Ihr Geldeingang zugeordnet werden kann: ';
+$_['text_payment_reference_only'] = 'Bitte verwenden Sie nur den unten angegebenen Verwendungszweck für die Überweisung, da nur so Ihr Geldeingang zugeordnet werden kann: ';
+$_['text_guarantee_payment_reference_transaction'] = 'Sobald die Bestellung abgeschickt wurde, wird die Zahlung bei Novalnet als Referenztransaktion verarbeitet.';
+$_['text_trial'] = '%s every %s %s for %s payments then ';
+$_['text_recurring'] = '%s every %s %s';
+$_['text_recurring_item'] = 'Recurring Item';
+$_['text_length'] = ' for %s payments';
+$_['text_test_order_notification'] = 'ehr geehrte Kundin, %s wir möchten Sie darüber informieren, dass eine Testbestellung %s kürzlich in Ihrem Shop durchgeführt wurde. Stellen Sie bitte sicher, dass für Ihr Projekt im Novalnet-Administrationsportal der Live-Modus gesetzt wurde und Zahlungen über Novalnet in Ihrem Shopsystem aktiviert sind. Ignorieren Sie bitte diese E-Mail, falls die Bestellung von Ihnen zu Testzwecken durchgeführt wurde.%sMit freundlichen Grüßen %sNovalnet AG';
+$_['text_test_order_notification_subject'] = 'Benachrichtigung zu Novalnet-Testbestellung - OPENCART';
+$_['text_guarantee_payment'] = 'Diese Transaktion wird mit Zahlungsgarantie verarbeitet';
+$_['text_novalnet_bank_comments'] = 'Überweisen Sie bitte den Betrag an die unten aufgeführte Bankverbindung unseres Zahlungsdienstleisters Novalnet.';
+$_['text_novalnet_account_holder'] = 'Kontoinhaber: ';
+$_['text_novalnet_due_date'] = 'Fälligkeitsdatum: ';
+$_['text_novalnet_slip_expiry_date'] = 'Verfallsdatum des Zahlscheins: ';
+$_['text_nearest_store_details'] = 'Barzahlen-Partnerfiliale in Ihrer Nähe';
+$_['text_novalnet_bank'] = 'Bank: ';
+$_['text_novalnet_iban'] = 'IBAN: ';
+$_['text_novalnet_bic'] = 'BIC: ';
+$_['text_novalnet_amount'] = 'Betrag: ';
+$_['text_novalnet_order_no'] = 'Bestellnummer ';
+$_['text_guarantee_payment_warning_msg'] = 'Die Zahlung kann nicht verarbeitet werden, weil die grundlegenden Anforderungen nicht erfüllt wurden. ';
+$_['text_recurring_cancel'] = 'Profil für wiederkehrende Zahlungen wurde storniert';
+$_['text_next_charging_date'] = 'Nächstes Belastungsdatum: ';
+$_['button_subscription_cancel'] = 'Abonnement kündigen';
+$_['text_recurring_orders'] = 'Novalnet-Bestellungen';
+$_['text_transaction_details'] = 'Novalnet-Transaktionsdetails';
+$_['text_recurring_date_not_met'] = 'Das nächste Buchungsdatum stimmt nicht mit dem nächsten Zahlungsdatum überein';
+$_['text_recurring_profile_canceled'] = 'Profil für wiederkehrende Zahlungen wurde storniert';
+$_['text_recurring_request_parameters'] = 'Parameter für den Aufruf des Servers im Profil für wiederkehrende Zahlungen';
+$_['text_recurring_response_parameters'] = 'Parameter für die Rückmeldung des Servers im Profil für wiederkehrende Zahlungen';
+$_['error_payment_not_successful'] = 'Die Zahlung war nicht erfolgreich. Ein Fehler trat auf.';
+$_['text_guarantee_pending_text'] = ' Ihre Bestellung ist unter Bearbeitung. Sobald diese bestätigt wurde, erhalten Sie alle notwendigen Informationen zum Ausgleich der Rechnung. Wir bitten Sie zu beachten, dass dieser Vorgang bis zu 24 Stunden andauern kann. ';
+$_['text_guarantee_pending_sepa_text'] = ' Ihre Bestellung wird derzeit überprüft. Wir werden Sie in Kürze über den Bestellstatus informieren. Bitte beachten Sie, dass dies bis zu 24 Stunden dauern kann. ';
diff --git a/catalog/language/de-de/extension/payment/novalnet_eps.php b/catalog/language/de-de/extension/payment/novalnet_eps.php
new file mode 100644
index 0000000..7a4d135
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_eps.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_giropay.php b/catalog/language/de-de/extension/payment/novalnet_giropay.php
new file mode 100644
index 0000000..b58614d
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_giropay.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_ideal.php b/catalog/language/de-de/extension/payment/novalnet_ideal.php
new file mode 100644
index 0000000..adfe851
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_ideal.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_instant_bank_transfer.php b/catalog/language/de-de/extension/payment/novalnet_instant_bank_transfer.php
new file mode 100644
index 0000000..4fa8307
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_instant_bank_transfer.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_invoice.php b/catalog/language/de-de/extension/payment/novalnet_invoice.php
new file mode 100644
index 0000000..f25faed
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_invoice.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_online_bank_transfer.php b/catalog/language/de-de/extension/payment/novalnet_online_bank_transfer.php
new file mode 100644
index 0000000..a576781
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_online_bank_transfer.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_paypal.php b/catalog/language/de-de/extension/payment/novalnet_paypal.php
new file mode 100644
index 0000000..3fc79c9
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_paypal.php
@@ -0,0 +1,27 @@
+';
+$_['novalnet_paypal_new_payment_details'] = 'Eingegebene Kontodaten';
+$_['novalnet_paypal_placed_payment_details'] = 'Neue Kontodaten für spätere Käufe hinzufügen';
+$_['novalnet_paypal_transaction_id'] = 'PayPal Transaktions-ID: ';
+$_['novalnet_paypal_novalnet_tid'] = 'Novalnet Transaktions-ID: ';
+$_['save_card_details'] = 'Meine PayPal-Daten für zukünftige Bestellungen speichern';
diff --git a/catalog/language/de-de/extension/payment/novalnet_prepayment.php b/catalog/language/de-de/extension/payment/novalnet_prepayment.php
new file mode 100644
index 0000000..a232b4d
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_prepayment.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_przelewy24.php b/catalog/language/de-de/extension/payment/novalnet_przelewy24.php
new file mode 100644
index 0000000..03b4013
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_przelewy24.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/de-de/extension/payment/novalnet_sepa.php b/catalog/language/de-de/extension/payment/novalnet_sepa.php
new file mode 100644
index 0000000..b786558
--- /dev/null
+++ b/catalog/language/de-de/extension/payment/novalnet_sepa.php
@@ -0,0 +1,39 @@
+
+
+ Gläubiger-Identifikationsnummer: DE53ZZZ00000004253
+
+
+ Hinweis: Ich kann innerhalb von acht Wochen, beginnend mit dem Belastungsdatum, die Erstattung des belasteten Betrages verlangen. Es gelten dabei die mit meinem Kreditinstitut vereinbarten Bedingungen.
+ ';
+$_['novalnet_sepa_payment_details_error'] = 'Ihre Kontodaten sind ungültig.';
+$_['error_sepa_mandate'] = 'Akzeptieren Sie bitte das SEPA-Lastschriftmandat';
+$_['error_sepa_due_date'] = 'SEPA Fälligkeitsdatum Ungültiger';
+$_['novalnet_sepa_new_account_details'] = 'Neue Kontodaten für spätere Käufe hinzufügen';
+$_['novalnet_sepa_given_account_details'] = 'Eingegebene Kontodaten';
+$_['payment_logo'] = ' ';
+$_['save_card_details'] = 'Meine Kontodaten für zukünftige Bestellungen speichern';
diff --git a/catalog/language/en-gb/callback/vendorScript.php b/catalog/language/en-gb/callback/vendorScript.php
new file mode 100644
index 0000000..93e6069
--- /dev/null
+++ b/catalog/language/en-gb/callback/vendorScript.php
@@ -0,0 +1,48 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_cc.php b/catalog/language/en-gb/extension/payment/novalnet_cc.php
new file mode 100644
index 0000000..3ec3a1e
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_cc.php
@@ -0,0 +1,41 @@
+';
+$_['payment_logo'] = ' ';
+$_['amex_logo'] = ' ';
+$_['zero_amount_desc'] ='' .'This order will be processed as zero amount booking which store your payment data for further online purchases.'.'
';
+$_['save_card_details'] ='Save my card details for future purchases';
+
diff --git a/catalog/language/en-gb/extension/payment/novalnet_common.php b/catalog/language/en-gb/extension/payment/novalnet_common.php
new file mode 100644
index 0000000..b9f4426
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_common.php
@@ -0,0 +1,73 @@
+The payment will be processed in the test mode therefore amount for this transaction will not be charged';
+$_['text_novalnet_TID'] = 'Novalnet transaction ID: ';
+$_['text_novalnet_test_order'] = 'Test order';
+$_['text_wait'] = 'Please wait...';
+$_['text_order_processed'] = 'Please wait, your order is being processed';
+$_['error_check_hash'] = 'While redirecting some data has been changed. The hash check failed.';
+$_['text_redirect'] = 'You will be redirected to the shop. Please wait';
+$_['text_barzahlen_payment_description'] = 'On successful checkout, you will receive a payment slip/SMS to pay your online purchase at one of our retail partners (e.g. supermarket).';
+$_['error_order_amount_changed'] = 'The order amount has been changed, please proceed with the new order';
+$_['text_guarantee_payment_dob'] = 'Your date of birth';
+$_['error_dob_empty'] = 'Please enter your date of birth';
+$_['error_dob_invalid_format'] = 'The date format is invalid';
+$_['error_sepa_age_below_18'] = 'You need to be at least 18 years old';
+$_['error_guarantee_billing_shipping_address'] = 'The billing address must be the same as the shipping address ';
+$_['error_guarantee_currency'] = 'Only EUR currency allowed ';
+$_['error_guarantee_minimum_amount'] = 'Minimum order amount must be ';
+$_['error_eur'] = ' EUR ';
+$_['error_guarantee_country'] = 'Only DE, CH countries allowed ';
+$_['error_callback_empty'] = 'Please enter your telephone number';
+$_['error_sms_empty'] = 'Please enter your mobile number';
+$_['text_payment_reference'] = 'Payment Reference';
+$_['text_payment_reference_any_one'] = 'Please use any one of the following references as the payment reference, as only through this way your payment is matched and assigned to the order: ';
+$_['text_payment_reference_only'] = 'Please use the following payment reference for your money transfer, as only through this way your payment is matched and assigned to the order: ';
+$_['text_guarantee_payment_reference_transaction'] = 'Once the order is submitted, the payment will be processed as a reference transaction at Novalnet';
+$_['text_trial'] = '%s every %s %s for %s payments then ';
+$_['text_recurring'] = '%s every %s %s';
+$_['text_recurring_item'] = 'Recurring Item';
+$_['text_length'] = ' for %s payments';
+$_['text_test_order_notification'] = 'Dear client, %sWe would like to inform you that test order %s has been placed in your shop recently.Please make sure your project is in LIVE mode at Novalnet administration portal and Novalnet payments are enabled in your shop system. Please ignore this email if the order has been placed by you for testing purpose.%sRegards,%sNovalnet AG';
+$_['text_test_order_notification_subject'] = 'Novalnet test order notification - OPENCART';
+$_['text_novalnet_bank_comments'] = 'Please transfer the amount to the below mentioned account details of our payment processor Novalnet';
+$_['text_guarantee_payment'] = 'This is processed as a guarantee payment ';
+$_['text_novalnet_account_holder'] = 'Account holder: ';
+$_['text_novalnet_due_date'] = 'Due date: ';
+$_['text_novalnet_slip_expiry_date'] = 'Slip expiry date: ';
+$_['text_nearest_store_details'] = 'Store(s) near you';
+$_['text_novalnet_bank'] = 'Bank: ';
+$_['text_novalnet_iban'] = 'IBAN: ';
+$_['text_novalnet_bic'] = 'BIC: ';
+$_['text_novalnet_amount'] = 'Amount: ';
+$_['text_novalnet_order_no'] = 'Order number ';
+$_['text_guarantee_payment_warning_msg'] = 'The payment cannot be processed, because the basic requirements haven’t been met. ';
+$_['text_recurring_cancel'] = 'Recurring order canceled.';
+$_['text_next_charging_date'] = 'Next charging date: ';
+$_['button_subscription_cancel'] = 'Cancel Subscription';
+$_['text_recurring_orders'] = 'Novalnet Orders';
+$_['text_transaction_details'] = 'Novalnet transaction details';
+$_['text_recurring_date_not_met'] = 'Recurring date does not meet the next payment date';
+$_['text_recurring_profile_canceled'] = 'Recurring profile canceled';
+$_['text_recurring_request_parameters'] = 'Recurring profile server request parameters';
+$_['text_recurring_response_parameters'] = 'Recurring profile server response parameters';
+$_['error_payment_not_successful'] = 'Payment was not successful. An error occurred.';
+$_['text_guarantee_pending_text'] = ' Your order is under verification and once confirmed, we will send you our bank details to where the order amount should be transferred. Please note that this may take upto 24 hours. ';
+$_['text_guarantee_pending_sepa_text'] = ' Your order is under verification and we will soon update you with the order status. Please note that this may take upto 24 hours. ';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_eps.php b/catalog/language/en-gb/extension/payment/novalnet_eps.php
new file mode 100644
index 0000000..d24b8ff
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_eps.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_giropay.php b/catalog/language/en-gb/extension/payment/novalnet_giropay.php
new file mode 100644
index 0000000..b56037c
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_giropay.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_ideal.php b/catalog/language/en-gb/extension/payment/novalnet_ideal.php
new file mode 100644
index 0000000..0eed9a4
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_ideal.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_instant_bank_transfer.php b/catalog/language/en-gb/extension/payment/novalnet_instant_bank_transfer.php
new file mode 100644
index 0000000..ab00374
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_instant_bank_transfer.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_invoice.php b/catalog/language/en-gb/extension/payment/novalnet_invoice.php
new file mode 100644
index 0000000..e2f051e
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_invoice.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_online_bank_transfer.php b/catalog/language/en-gb/extension/payment/novalnet_online_bank_transfer.php
new file mode 100644
index 0000000..ca19197
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_online_bank_transfer.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_paypal.php b/catalog/language/en-gb/extension/payment/novalnet_paypal.php
new file mode 100644
index 0000000..2202688
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_paypal.php
@@ -0,0 +1,28 @@
+';
+$_['novalnet_paypal_new_payment_details'] = 'Given account details';
+$_['novalnet_paypal_placed_payment_details'] = 'Add new account details for later purchases';
+$_['novalnet_paypal_transaction_id'] = 'PayPal transaction ID: ';
+$_['novalnet_paypal_novalnet_tid'] = 'Novalnet transaction ID: ';
+$_['zero_amount_desc'] ='' .'This order will be processed as zero amount booking which store your payment data for further online purchases.'.'
';
+$_['save_card_details'] ='Save my PayPal details for future purchases';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_prepayment.php b/catalog/language/en-gb/extension/payment/novalnet_prepayment.php
new file mode 100644
index 0000000..605aa09
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_prepayment.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_przelewy24.php b/catalog/language/en-gb/extension/payment/novalnet_przelewy24.php
new file mode 100644
index 0000000..ee7f637
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_przelewy24.php
@@ -0,0 +1,22 @@
+';
diff --git a/catalog/language/en-gb/extension/payment/novalnet_sepa.php b/catalog/language/en-gb/extension/payment/novalnet_sepa.php
new file mode 100644
index 0000000..994df26
--- /dev/null
+++ b/catalog/language/en-gb/extension/payment/novalnet_sepa.php
@@ -0,0 +1,39 @@
+
+
+ Creditor identifier: DE53ZZZ00000004253
+
+
+ Note: You are entitled to a refund from your bank under the terms and conditions of your agreement with bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited.';
+$_['novalnet_sepa_payment_details_error'] = 'Your account details are invalid';
+$_['error_sepa_mandate'] = 'Please accept the SEPA direct debit mandate';
+$_['error_sepa_due_date'] = 'SEPA Due date is not valid';
+$_['novalnet_sepa_new_account_details'] = 'Add new account details for later purchases';
+$_['novalnet_sepa_given_account_details'] = 'Given account details';
+$_['payment_logo'] = ' ';
+$_['zero_amount_desc'] ='' .'This order will be processed as zero amount booking which store your payment data for further online purchases.'.'
';
+$_['save_card_details'] ='Save my account details for future purchases';
diff --git a/catalog/model/extension/payment/novalnet.php b/catalog/model/extension/payment/novalnet.php
new file mode 100644
index 0000000..e495e9d
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet.php
@@ -0,0 +1,1583 @@
+ array(
+ 'key' => '6',
+ 'payment_type' => 'CREDITCARD'
+ ),
+ 'novalnet_sepa' => array(
+ 'key' => '37',
+ 'payment_type' => 'DIRECT_DEBIT_SEPA'
+ ),
+ 'novalnet_instant_bank_transfer' => array(
+ 'key' => '33',
+ 'payment_type' => 'ONLINE_TRANSFER'
+ ),
+ 'novalnet_paypal' => array(
+ 'key' => '34',
+ 'payment_type' => 'PAYPAL'
+ ),
+ 'novalnet_ideal' => array(
+ 'key' => '49',
+ 'payment_type' => 'IDEAL'
+ ),
+ 'novalnet_eps' => array(
+ 'key' => '50',
+ 'payment_type' => 'EPS'
+ ),
+ 'novalnet_giropay' => array(
+ 'key' => '69',
+ 'payment_type' => 'GIROPAY'
+ ),
+ 'novalnet_invoice' => array(
+ 'key' => '27',
+ 'payment_type' => 'INVOICE'
+ ),
+ 'novalnet_prepayment' => array(
+ 'key' => '27',
+ 'payment_type' => 'PREPAYMENT'
+ ),
+ 'novalnet_przelewy24' => array(
+ 'key' => '78',
+ 'payment_type' => 'PRZELEWY24'
+ ),
+ 'novalnet_invoice_guarantee' => array(
+ 'key' => '41',
+ 'payment_type' => 'GUARANTEED_INVOICE',
+ ),
+ 'novalnet_sepa_guarantee' => array(
+ 'key' => '40',
+ 'payment_type' => 'GUARANTEED_DIRECT_DEBIT_SEPA',
+ ),
+ 'novalnet_cashpayment' => array(
+ 'key' => '59',
+ 'payment_type' => 'CASHPAYMENT',
+ ),
+ 'novalnet_online_bank_transfer'=>array(
+ 'key' => '113',
+ 'payment_type' => 'ONLINE_BANK_TRANSFER',
+ ),
+ );
+
+ /**
+ * To display the payment in front end.
+ *
+ * @param $address
+ * @param $total
+ * @return none
+ */
+ public function getMethod($address, $total)
+ {
+ return array();
+ }
+
+ /**
+ * Get payment method details
+ *
+ * @param $address
+ * @param $total
+ * @param $payment_name
+ * @return array
+ */
+ public function getOptionMethod($address, $total, $payment_name) {
+ $configuration_status = $this->config->get('payment_'.$payment_name . '_status');
+ $this->load->language('extension/payment/' . $payment_name);
+ if ((trim($this->config->get('payment_novalnet_public_key')) == '' && $configuration_status)) {
+ return false;
+ }
+ return $configuration_status;
+ }
+
+ /**
+ * Unset payment session values before displaying payment
+ *
+ * @param $payment_name
+ * @return none
+ */
+ public function unsetBeforePaymentSession($payment_name) {
+ if ($payment_name != 'payment_novalnet_sepa' && !empty($this->session->data['novalnet_sepa'])) {
+ unset($this->session->data['novalnet_sepa']);
+ } else if ($payment_name != 'payment_novalnet_invoice' && !empty($this->session->data['novalnet_invoice'])) {
+ unset($this->session->data['novalnet_invoice']);
+ }
+ }
+
+ /**
+ * Validate allowed countries
+ *
+ * @param $country
+ * @return boolean
+ */
+ public function validateAllowedCountries($country)
+ {
+ return in_array($country, array(
+ 'AT',
+ 'DE',
+ 'CH'
+ ));
+ }
+
+ /**
+ * Get merchant details
+ *
+ * @return array
+ */
+ public function getMerchantDetails() {
+
+ // Get tariff type and value.
+ $vendor_parameters = array(
+ 'vendor' => trim($this->config->get('payment_novalnet_merchant_id')),
+ 'product' => trim($this->config->get('payment_novalnet_project_id')),
+ 'tariff' => $this->getTariffId(),
+ 'auth_code' => trim($this->config->get('payment_novalnet_authcode')),
+ );
+ $this->session->data['nn']['payment_access_key'] = trim($this->config->get('payment_novalnet_access_key'));
+
+ return $vendor_parameters;
+ }
+
+ /**
+ * Get Tariff details
+ *
+ * @param $get_tariff_type
+ * @return integer
+ */
+ public function getTariffId($get_tariff_type = false) {
+ $tariff_id = explode('-', $this->config->get('payment_novalnet_tariff_id'));
+ return ($get_tariff_type) ? $tariff_id['1'] : $tariff_id['0'];
+ }
+
+ /**
+ * Get Customer parameters
+ *
+ * @param $order_info
+ * @return array
+ */
+ public function getCustomerParameters($order_info) {
+ $first_name = trim($order_info['payment_firstname']);
+ $last_name = trim($order_info['payment_lastname']);
+
+ // Check for first name and lastname
+ if (in_array('', array($first_name, $last_name))) {
+ $name = $first_name . $last_name;
+ list($first_name, $last_name) = (preg_match('/\s/', $name)) ? explode(' ', $name, 2) : array($name, $name);
+ }
+ return array(
+ 'gender' => 'u',
+ 'first_name' => $first_name,
+ 'last_name' => $last_name,
+ 'email' => trim($order_info['email']),
+ 'street' => (!empty($order_info['payment_address_2'])) ? $order_info['payment_address_1'] . ', ' . $order_info['payment_address_2'] : $order_info['payment_address_1'],
+ 'search_in_street' => 1,
+ 'city' => $order_info['payment_city'],
+ 'zip' => $order_info['payment_postcode'],
+ 'tel' => trim($order_info['telephone']),
+ 'country' => $order_info['payment_iso_code_2'],
+ 'country_code' => $order_info['payment_iso_code_2'],
+ 'customer_no' => !empty($order_info['customer_id']) && ($order_info['customer_id'] > 0) ? $order_info['customer_id'] : 'guest',
+ );
+ }
+
+ /**
+ * Get Payment parameters
+ *
+ * @param $payment_name
+ * @param $order_info
+ * @return array
+ */
+ public function getParameters($payment_name, $order_info = '') {
+
+ // Get order details.
+ if(empty($order_info)) {
+ $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
+ }
+ $language = $this->getLanguageCode($order_info['language_code']);
+
+ // Form Vendor parameters.
+ $vendor_parameters = $this->getMerchantDetails();
+
+ // Form Customer parameters.
+ $customer_parameters = $this->getCustomerParameters($order_info);
+ $payment_key = $this->session->data['nn_payment_key'] = $this->payment_details[$payment_name]['key'];
+
+ // Form order parameters.
+ $order_parameters = array(
+ 'currency' => $order_info['currency_code'],
+ 'amount' => $this->getAmountFormat($order_info['total'], $order_info['currency_value']),
+ 'order_no' => $order_info['order_id'],
+ 'lang' => $language,
+ 'language' => $language,
+ 'key' => $payment_key,
+ 'test_mode' => ($this->config->get('payment_'.$payment_name . '_testmode')),
+ 'payment_type' => $this->payment_details[$payment_name]['payment_type'],
+ );
+
+ // Form System parameters.
+ $system_parameters = array(
+ 'remote_ip' => $this->getIpAddress('REMOTE_ADDR'),
+ 'system_name' => 'opencart',
+ 'system_version' => VERSION . '-' . 'NN_11.5.0',
+ 'system_url' => ($this->request->server['HTTPS']) ? HTTPS_SERVER : HTTP_SERVER,
+ 'system_ip' => $this->getIpAddress('SERVER_ADDR')
+ );
+
+ // Form Additional parametrs.
+ $additional_parameters = array_filter(array(
+ 'company' => trim($order_info['payment_company']),
+ 'notify_url' => trim($this->config->get('payment_novalnet_notification_url')),
+ 'input3' => 'session_name',
+ 'inputval3' => $this->config->get('session_name'),
+ 'input4' => 'session_id',
+ 'inputval4' => $this->session->getId(),
+ ));
+
+ return array_merge($vendor_parameters, $customer_parameters, $order_parameters, $system_parameters, $additional_parameters);
+ }
+
+ /**
+ * Generate random unique id
+ *
+ * @param none
+ * @return string
+ */
+ function novalnet_get_random_string() {
+ $randomwordarray = explode(',', '8,7,6,5,4,3,2,1,9,0,9,7,6,1,2,3,4,5,6,7,8,9,0');
+ shuffle($randomwordarray);
+ return substr(implode( '', $randomwordarray ), 0, 16);
+ }
+
+ /**
+ * Get Redirect parameters
+ *
+ * @param $parameters
+ * @param $payment_name
+ * @return array
+ */
+
+ public function getRedirectParameters($parameters, $payment_name){
+ $this->return_url = $this->url->link('extension/payment/' . $payment_name . '/callback', '', true);
+ $parameters['uniqid'] = $this->novalnet_get_random_string();
+ $this->encode($parameters, array(
+ 'auth_code',
+ 'product',
+ 'tariff',
+ 'amount',
+ 'test_mode',
+ ));
+ $parameters['hash'] = $this->generateHashValue($parameters);
+ $parameters = $this->getReturnUrl($parameters);
+ return $parameters;
+ }
+
+ /**
+ * Perform redirect payment post process
+ *
+ * @param $url
+ * @param $parameters
+ * @param $payment_name
+ * @return array
+ */
+ public function performRedirectProcess($url, $parameters, $payment_name)
+ {
+ $this->language->load('extension/payment/' . $payment_name);
+ $json['data_redirect'] = ' ';
+ foreach ($parameters as $key => $value) {
+ $json['data_redirect'] .= ' ' . "\n";
+ }
+ $json['data_redirect'] .= ' ';
+ return $json;
+ }
+
+ /**
+ * Perform redirect payment process
+ *
+ * @param $payment_name
+ * @return array
+ */
+ public function checkRedirectPaymentProcess($payment_name) {
+ $server_response = $this->request->request;
+
+ if (empty($this->session->data['nn'])) {
+
+ $session_name = ($server_response['inputval3'] ? $server_response['inputval3'] : ($server_response['session_name'] ? $server_response['session_name'] : ''));
+
+ $session_id = ($server_response['inputval4'] ? $server_response['inputval4'] : ($server_response['session_id'] ? $server_response['session_id'] : ''));
+
+ $this->session->start($session_id);
+ setcookie($session_name, $session_id, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'));
+ }
+
+ if ($server_response['status'] == '100' ) {
+ if($this->checkHashFailed($server_response)) {
+ return array(
+ 'type' => 'failure',
+ 'error' => $this->language->get('error_check_hash'),
+ );
+ }
+ $this->decode($server_response);
+ return $server_response;
+ }
+ return array(
+ 'type' => 'failure',
+ 'error' => $this->setResponseMessage($server_response),
+ );
+ }
+
+ /**
+ * To check both request and response hash value
+ *
+ * @param $server_response
+ * @return boolean
+ */
+ public function checkHashFailed($server_response)
+ {
+ return (empty($server_response['hash2']) || $server_response['hash2'] != $this->generateHashValue($server_response));
+ }
+
+ /**
+ * To encode the given data
+ *
+ * @param $data
+ * @param $encoded_params
+ * @return none
+ */
+ public function encode(&$data, $encoded_params) {
+
+ foreach ($encoded_params as $value) {
+ $encoded_data = $data[$value];
+ $encode_data= htmlentities(
+ base64_encode(
+ openssl_encrypt($encoded_data, "aes-256-cbc", $this->session->data['nn']['payment_access_key'], true, $data['uniqid'])
+ )
+ );
+ $data[$value] = $encode_data;
+ }
+ }
+
+ /**
+ * To decode the given data
+ *
+ * @param $data
+ * @return string
+ */
+ public function decode(&$data) {
+ $decode_params = array('product', 'tariff', 'test_mode', 'amount', 'auth_code');
+
+ foreach ($decode_params as $param) {
+ try {
+ if (isset($data[$param])) {
+ $data[$param] = $this->novalnet_decrypt($data[$param], $data['uniqid'], $this->session->data['nn']['payment_access_key']);
+ }
+ }
+ catch (Exception $e) {
+
+ return FALSE;
+ }
+ }
+ }
+
+ /**
+ * To decode the given data
+ *
+ * @param $data
+ * @param $uniqid
+ * @param $key
+ * @return string
+ */
+ public function novalnet_decrypt($data, $uniqid, $key) {
+ // Return decrypted Data.
+ $decript=openssl_decrypt(
+ base64_decode($data),
+ "aes-256-cbc", $key, true, $uniqid
+ );
+ return $decript;
+ }
+
+ /**
+ * To generate hash value
+ *
+ * @param $data
+ * @return string
+ */
+ public function generateHashValue($data) {
+ $key=$this->session->data['nn']['payment_access_key'];
+ $hash = '';
+ foreach (array('auth_code', 'product', 'tariff', 'amount', 'test_mode', 'uniqid') as $params) {
+
+ $hash .= $data[$params];
+
+ }
+ $hash .= strrev($key);
+
+ return hash('sha256', $hash);
+ }
+
+ /**
+ * Get return url parameters
+ *
+ * @param $parameters
+ * @return none
+ */
+ public function getReturnUrl($parameters)
+ {
+ $parameters['return_url'] = $parameters['error_return_url'] = $this->return_url;
+ $parameters['return_method'] = $parameters['error_return_method'] = 'POST';
+ $parameters['implementation'] = 'ENC';
+ $parameters['user_variable_0'] = ($this->request->server['HTTPS']) ? HTTPS_SERVER : HTTP_SERVER;
+ return $parameters;
+ }
+
+ /**
+ * Handle susbscription process for Opencart (version > 3.0.0.0)
+ *
+ * @param $response
+ * @param $order_info
+ * @param $transaction_comments
+ * @return none
+ */
+ public function handleSubscriptionProcess($response, $order_info, $transaction_comments) {
+
+ $recurring_products = $this->cart->getRecurringProducts();
+ $this->load->model('checkout/recurring');
+ $this->load->model('account/recurring');
+ foreach($recurring_products as $recurring_product ) {
+ // Get trial details.
+ $subscription_trial_details = '';
+ $recurring_product['recurring']['product_id'] = $recurring_product['product_id'];
+ $recurring_product['recurring']['quantity'] = $recurring_product['quantity'];
+
+
+ //trial information
+ if ($recurring_product['recurring']['trial'] == 1) {
+ $trial_amt = $this->currency->format($this->tax->calculate($recurring_product['recurring']['trial_price'], $recurring_product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $recurring_product['quantity'] . ' ' . $this->session->data['currency'];
+ $trial_text = sprintf($this->language->get('text_trial'), $trial_amt, $recurring_product['recurring']['trial_cycle'], $recurring_product['recurring']['trial_frequency'], $recurring_product['recurring']['trial_duration']);
+
+ } else {
+ $trial_text = '';
+ }
+ $recurring_amt = $this->currency->format($this->tax->calculate($recurring_product['recurring']['price'], $recurring_product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $recurring_product['quantity'] . ' ' . $this->session->data['currency'];
+
+ $recurring_description = $trial_text . sprintf($this->language->get('text_recurring'), $recurring_amt, $recurring_product['recurring']['cycle'], $recurring_product['recurring']['frequency']);
+
+ if ($recurring_product['recurring']['duration'] > 0) {
+ $recurring_description .= sprintf($this->language->get('text_length'), $recurring_product['recurring']['duration']);
+ }
+ $recurring_id = $this->model_checkout_recurring->addRecurring($order_info['order_id'], $recurring_description, $recurring_product);
+ $next_payment = new DateTime('now');
+ $trial_end = new DateTime('now');
+ $recurring_end = new DateTime('now');
+ list($next_payment, $trial_end, $recurring_end) = $this->calculatePaymentDate($recurring_product, $next_payment, $trial_end, $recurring_end);
+ $subscription_recurring_details = json_encode(array(
+ 'recurring_frequency' => $recurring_product['recurring']['frequency'],
+ 'recurring_duration' => $recurring_product['recurring']['duration'],
+ 'recurring_cycle' => $recurring_product['recurring']['cycle'],
+ 'recurring_price' => $this->getAmountFormat($recurring_product['recurring']['price']),
+ 'recurring_period_end' => date_format($recurring_end, 'Y-m-d'),
+ ));
+
+ // Check for trial details.
+ if($recurring_product['recurring']['trial']) {
+ $subscription_trial_details = json_encode(array(
+ 'trial_frequency' => $recurring_product['recurring']['trial_frequency'],
+ 'trial_duration' => $recurring_product['recurring']['trial_duration'],
+ 'trial_cycle' => $recurring_product['recurring']['trial_cycle'],
+ 'trial_price' => $this->getAmountFormat($recurring_product['recurring']['trial_price']),
+ 'trial_period_end' => date_format($trial_end, 'Y-m-d'),
+ ));
+ }
+ $this->model_checkout_recurring->editReference($recurring_id, $response['tid']);
+ $recurring = $this->getNovalnetOrderRecurringStatus($recurring_id);
+ if ($recurring['status'] != '1') {
+ $this->model_account_recurring->editOrderRecurringStatus($recurring_id, '1');
+ }
+ $this->storeNovalnetSubscriptions(array(
+ 'order_no' => $order_info['order_id'],
+ 'order_recurring_id ' => $recurring_id,
+ 'tid' => $response['tid'],
+ 'next_subs_cycle' => date_format($next_payment, 'Y-m-d'),
+ 'trial_details' => $subscription_trial_details,
+ 'recurring_details' => $subscription_recurring_details,
+ 'additional_details' => json_encode($recurring_products),
+ ));
+ $amount = ($order_info['payment_code'] == 'novalnet_paypal') ? $response['amount']/100 : $response['amount'];
+ $this->storeNovalnetRecurring(array(
+ 'order_no' => $order_info['order_id'],
+ 'order_recurring_id' => $recurring_id,
+ 'tid' => $response['tid'],
+ 'amount' => $this->currency->format($amount, $order_info['currency_code'],1),
+ 'payment_type' => $order_info['payment_code'],
+ 'transaction_details' => $transaction_comments,
+ 'status' => ($response['tid_status'] == '100') ? 'paid' : 'unpaid',
+ 'date_added' => date("Y-m-d H:i:s")
+ ));
+ }
+ }
+
+ /**
+ * Handle susbscription process for Opencart version 3.0.0.0
+ *
+ * @param $response
+ * @param $order_info
+ * @param $transaction_comments
+ * @return none
+ */
+
+ public function handleOldSubscriptionProcess($response, $order_info, $transaction_comments) {
+ $recurring_products = $this->cart->getRecurringProducts();
+ $this->load->model('checkout/recurring');
+ $this->load->model('account/recurring');
+ foreach($recurring_products as $recurring_product ) {
+ // Get trial details.
+ $subscription_trial_details = '';
+ $recurring_id = $this->model_checkout_recurring->create($recurring_product, $order_info['order_id'], $transaction_comments);
+ $next_payment = new DateTime('now');
+ $trial_end = new DateTime('now');
+ $recurring_end = new DateTime('now');
+ list($next_payment, $trial_end, $recurring_end) = $this->calculatePaymentDate($recurring_product, $next_payment, $trial_end, $recurring_end);
+ $subscription_recurring_details = json_encode(array(
+ 'recurring_frequency' => $recurring_product['recurring']['frequency'],
+ 'recurring_duration' => $recurring_product['recurring']['duration'],
+ 'recurring_cycle' => $recurring_product['recurring']['cycle'],
+ 'recurring_price' => $this->getAmountFormat($recurring_product['recurring']['price']),
+ 'recurring_period_end' => date_format($recurring_end, 'Y-m-d'),
+ ));
+ // Check for trial details.
+ if($recurring_product['recurring']['trial']) {
+ $subscription_trial_details = json_encode(array(
+ 'trial_frequency' => $recurring_product['recurring']['trial_frequency'],
+ 'trial_duration' => $recurring_product['recurring']['trial_duration'],
+ 'trial_cycle' => $recurring_product['recurring']['trial_cycle'],
+ 'trial_price' => $this->getAmountFormat($recurring_product['recurring']['trial_price']),
+ 'trial_period_end' => date_format($trial_end, 'Y-m-d'),
+ ));
+ }
+ $this->model_checkout_recurring->addReference($recurring_id, $response['tid']);
+ $recurring = $this->getNovalnetOrderRecurringStatus($recurring_id);
+ if ($recurring['status'] != '1') {
+ $this->model_account_recurring->editOrderRecurringStatus($recurring_id, '1');
+ }
+ $this->storeNovalnetSubscriptions(array(
+ 'order_no' => $order_info['order_id'],
+ 'order_recurring_id ' => $recurring_id,
+ 'tid' => $response['tid'],
+ 'next_subs_cycle' => date_format($next_payment, 'Y-m-d'),
+ 'trial_details' => $subscription_trial_details,
+ 'recurring_details' => $subscription_recurring_details,
+ 'additional_details' => json_encode($recurring_products),
+ ));
+ }
+ }
+
+ /**
+ * Return recurring order status
+ *
+ * @param $order_recurring_id
+ * @return array
+ */
+ public function getNovalnetOrderRecurringStatus($order_recurring_id){
+ return $this->dbSelect('order_recurring', 'status', 'order_recurring_id=' . $order_recurring_id);
+ }
+
+ /**
+ * Calculate payment date
+ *
+ * @param $recurring_product
+ * @param $next_payment
+ * @param $trial_end
+ * @param $recurring_end
+ * @return array
+ */
+ public function calculatePaymentDate($recurring_product, $next_payment, $trial_end, $recurring_end) {
+
+ if ($recurring_product['recurring']['trial'] == 1 && $recurring_product['recurring']['trial_duration'] != 0) {
+ $next_payment = $this->calculateSubscriptionSchedule($recurring_product['recurring']['trial_frequency'], $next_payment, $recurring_product['recurring']['trial_cycle']);
+
+ $trial_end = $this->calculateSubscriptionSchedule($recurring_product['recurring']['trial_frequency'], $trial_end, $recurring_product['recurring']['trial_cycle'] * $recurring_product['recurring']['trial_duration']);
+
+ } elseif ($recurring_product['recurring']['trial'] == 1) {
+ $next_payment = $this->calculateSubscriptionSchedule($recurring_product['recurring']['trial_frequency'], $next_payment, $recurring_product['recurring']['trial_cycle']);
+ $trial_end = new DateTime('0000-00-00');
+ }
+
+ if ($trial_end > $recurring_end && $recurring_product['recurring']['duration'] != 0) {
+ $recurring_end = new DateTime(date_format($trial_end, 'Y-m-d H:i:s'));
+ $recurring_end = $this->calculateSubscriptionSchedule($recurring_product['recurring']['frequency'], $recurring_end, $recurring_product['recurring']['cycle'] * $recurring_product['recurring']['duration']);
+ } elseif ($trial_end == $recurring_end && $recurring_product['recurring']['duration'] != 0) {
+ $next_payment = $this->calculateSubscriptionSchedule($recurring_product['recurring']['frequency'], $next_payment, $recurring_product['recurring']['cycle']);
+
+ $recurring_end = $this->calculateSubscriptionSchedule($recurring_product['recurring']['frequency'], $recurring_end, $recurring_product['recurring']['cycle'] * $recurring_product['recurring']['duration']);
+ } elseif ($trial_end > $recurring_end && $recurring_product['recurring']['duration'] == 0) {
+ $recurring_end = new DateTime('0000-00-00');
+ } elseif ($trial_end == $recurring_end && $recurring_product['recurring']['duration'] == 0) {
+ $next_payment = $this->calculateSubscriptionSchedule($recurring_product['recurring']['frequency'], $next_payment, $recurring_product['recurring']['cycle']);
+
+ $recurring_end = new DateTime('0000-00-00');
+ }
+ return array($next_payment, $trial_end, $recurring_end);
+ }
+
+ /**
+ * Perform Novalnet success transaction process
+ *
+ * @param $response
+ * @param $payment_name
+ * @return array
+ */
+ public function transactionSuccess($response, $payment_name) {
+ $payment_type = $payment_name;
+ $payment_name = 'payment_'.$payment_name;
+ $this->load->model('checkout/order');
+ // Get order data.
+ $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
+ // Prepare transaction comments.
+ $transaction_comments = $this->prepareTransactionComments($response, $payment_type);
+
+ // Handle subscription process.
+ if(VERSION == '3.0.0.0') {
+ $this->handleOldSubscriptionProcess($response, $order_info, $transaction_comments);
+ }
+ else {
+ $this->handleSubscriptionProcess($response, $order_info, $transaction_comments);
+ }
+ // Get amount in cents.
+ $formated_amount = $this->getAmountFormat($order_info['total'], $order_info['currency_value']);
+
+ $pending_payment = in_array($response['tid_status'], array('86', '90'));
+
+ $invoice_payment = in_array($payment_type, array('novalnet_invoice', 'novalnet_prepayment', 'novalnet_cashpayment'));
+
+ // Get order status.
+ if (in_array($response['payment_id'], array('40', '41')) && $response['tid_status'] == '75') {
+ $order_status = $this->config->get($payment_name . '_guarantee_pending_order_status');
+ } else if(in_array($response['tid_status'], array('86', '90'))) {
+ $order_status = $this->config->get($payment_name . '_pending_order_status');
+ }else if( in_array($response['tid_status'], array('85', '91', '98', '99')) ) {
+ $order_status = $this->config->get('payment_novalnet_onhold_complete_status');
+ } else {
+ $order_status = $this->config->get($payment_name . '_order_completion_status');
+ }
+
+ $configuration_details = $this->getMerchantDetails();
+
+ // Insert transaction details
+ $this->storeNovalnetTransactions(array(
+ 'order_no' => $order_info['order_id'],
+ 'tid' => $response['tid'],
+ 'gateway_status' => $response['tid_status'],
+ 'payment_type' => $payment_type,
+ 'payment_id' => $this->session->data['nn_payment_key'],
+ 'customer_id' => $order_info['customer_id'],
+ 'create_payment_ref' => (int) !empty($response['create_payment_ref']) && $this->config->get($payment_name.'_shopping_type') == 'ONE_CLICK' ? 1 : 0,
+ 'payment_configurations' => json_encode(array(
+ 'vendor' => $configuration_details['vendor'],
+ 'product' => $configuration_details['product'],
+ 'tariff' => $configuration_details['tariff'],
+ 'auth_code' => $configuration_details['auth_code'],
+ 'test_mode' => (int) ((!empty($response['test_mode']) && $response['test_mode']) || ($this->config->get($payment_name . '_testmode') == '1')),
+ )),
+ 'transaction_details' => json_encode(array(
+ 'amount' => ($this->config->get($payment_name.'_shopping_type') == 'ZERO_AMOUNT' && $this->getTariffId(true) == '2') ? 0 : $formated_amount,
+ 'total_amount' => $formated_amount,
+ 'refund_amount' => 0,
+ 'currency' => $order_info['currency_code'],
+ 'reference_tid' => !empty($this->session->data[$payment_name . '_reference_tid']) ? $this->session->data[$payment_name . '_reference_tid'] : 'NULL',
+ )),
+ 'one_click_details' => !empty($response['one_click_details']) ? $response['one_click_details'] : '',
+ 'zero_amount_details' => (($this->config->get($payment_name.'_shopping_type') == 'ZERO_AMOUNT' && $this->getTariffId(true) == '2') && (!in_array($response['payment_id'], array('40', '41')) && $response['tid_status'] != '75')) ? addslashes(json_encode($this->session->data[$payment_type]['payment_params'])) : 0,
+ 'additional_details' => !empty($response['additional_details']) ? addslashes($response['additional_details']) : '',
+ ));
+ // Insert callback details.
+ $this->storeMerchantScriptDetails(array(
+ 'order_no' => $order_info['order_id'],
+ 'original_tid' => $response['tid'],
+ 'callback_tid' => $response['tid'],
+ 'payment_type' => $payment_type,
+ 'amount' => ($invoice_payment || $pending_payment) ? 0 : $formated_amount,
+ ));
+ // Unset Novalnet sessions.
+ $this->unsetSessionValues($payment_type);
+ return array(
+ 'orderStatus' => $order_status,
+ 'novalnet_comments' => $transaction_comments,
+ 'order_info' => $order_info,
+ );
+ }
+
+ /**
+ * Insert details into the Novalnet transactions table
+ *
+ * @param $transaction_details
+ * @return none
+ */
+ public function storeNovalnetTransactions($transaction_details) {
+ foreach ($transaction_details as $key => $value) {
+ $transaction_details[$key] = "'" . $transaction_details[$key] . "'";
+ }
+ $transaction_details['date'] = "'" . date('Y-m-d H:i:s') . "'";
+ $this->dbInsert('novalnet_transactions', array_keys($transaction_details), $transaction_details);
+ }
+
+ /**
+ * Insert details into the Novalnet subscriptions table
+ *
+ * @param $subscription_details
+ * @return none
+ */
+ public function storeNovalnetSubscriptions($subscription_details) {
+
+ foreach ($subscription_details as $key => $value) {
+ $subscription_details[$key] = "'" . $subscription_details[$key] . "'";
+ }
+ $this->dbInsert('novalnet_subscriptions', array_keys($subscription_details), $subscription_details);
+ }
+
+ /**
+ * Insert details into the Novalnet recurring table
+ *
+ * @param $recurring_details
+ * @return none
+ */
+ public function storeNovalnetRecurring($recurring_details) {
+
+ foreach ($recurring_details as $key => $value) {
+ $recurring_details[$key] = "'" . $recurring_details[$key] . "'";
+ }
+ $this->dbInsert('novalnet_recurring_transactions', array_keys($recurring_details), $recurring_details);
+ }
+
+ /**
+ * Insert and Update shop information into the database
+ *
+ * @param $merchant_script_details
+ * @return none
+ */
+ public function storeMerchantScriptDetails($merchant_script_details)
+ {
+ foreach ($merchant_script_details as $key => $value) {
+ $merchant_script_details[$key] = "'" . $merchant_script_details[$key] . "'";
+ }
+ $merchant_script_details['date'] = "'" . date('Y-m-d H:i:s') . "'";
+ $this->dbInsert('novalnet_merchant_script', array_keys($merchant_script_details), $merchant_script_details);
+ }
+
+ /**
+ * Unset payment session values after order completion
+ *
+ * @param $payment_name
+ * @return none
+ */
+ public function unsetSessionValues($payment_name)
+ {
+ if (!empty($this->session->data[$payment_name])) {
+ unset($this->session->data[$payment_name]);
+ }
+ if (!empty($this->session->data[$payment_name . '_payment_parameters'])) {
+ unset($this->session->data[$payment_name . '_payment_parameters']);
+ }
+ if (!empty($this->session->data['nn_payment_key'])) {
+ unset($this->session->data['nn_payment_key']);
+ }
+ if (!empty($this->session->data['new_or_placed_payment_details'])) {
+ unset($this->session->data['new_or_placed_payment_details']);
+ }
+ if (!empty($this->session->data['nn']['payment_access_key'])) {
+ unset($this->session->data['nn']['payment_access_key']);
+ }
+ if (!empty($this->session->data[$payment_name . '_reference_tid'])) {
+ unset($this->session->data[$payment_name . '_reference_tid']);
+ }
+ }
+
+ /**
+ * Insert values into the database
+ *
+ * @param $table_name
+ * @param $insert_columns
+ * @param $insert_values
+ * @return none
+ */
+ public function dbInsert($table_name, $insert_columns, $insert_values) {
+ $get_columns = implode(',', $insert_columns);
+ $get_values = implode(',', $insert_values);
+ $this->db->query("INSERT INTO " . DB_PREFIX . $table_name . "(" . $get_columns . ") values (" . $get_values . ")");
+ }
+
+ /**
+ * Select the database row values
+ *
+ * @param $table_name
+ * @param $fields
+ * @param $conditions
+ * @param $check
+ * @return array
+ */
+ public function dbSelect($table_name, $fields, $conditions, $check=false)
+ {
+ $select_query = 'SELECT ' . $fields . ' FROM ' . DB_PREFIX . $table_name . ' WHERE ' . $conditions;
+ $result = $this->db->query($select_query);
+ return ($check) ? $result->rows : $result->row;
+ }
+
+ /**
+ * Update the values into the database
+ *
+ * @param $table_name
+ * @param $fields
+ * @param $conditions
+ * @return none
+ */
+ public function dbUpdate($table_name, $fields, $conditions) {
+ $get_fields = '';
+ if (is_array($fields)) {
+ foreach ($fields as $key => $value) {
+ $get_fields .= $key . '=' . $value . ',';
+ }
+ $get_fields = substr($get_fields, 0, -1);
+ } else {
+ $get_fields = $fields;
+ }
+ $this->db->query("UPDATE " . DB_PREFIX . $table_name . " SET " . $get_fields . " WHERE " . $conditions);
+ }
+
+ /**
+ * Prepare Novalnet transaction comments
+ *
+ * @param $response
+ * @param $order_info
+ * @param $payment_name
+ * @param $order_id
+ * @return string
+ */
+ public function prepareNovalnetComments($response, $order_info, $callback = false)
+ {
+ $novalnet_comments = '';
+ $novalnet_comments .= $this->prepareBankDetailsComments($response, $order_info, $callback);
+ return $novalnet_comments;
+ }
+
+ /**
+ * Prepare Bank details comments
+ *
+ * @param $response
+ * @param $order_info
+ * @return string
+ */
+ public function prepareBankDetailsComments($response, $order_info, $callback = false)
+ {
+ $novalnet_comments = ' ' . $this->language->get('text_novalnet_bank_comments') . ' ';
+ if($response['tid_status'] == '100' && !empty($response['due_date'])) {
+ $novalnet_comments .= $this->language->get('text_novalnet_due_date') . date($this->language->get('date_format_short'), strtotime($response['due_date'])). ' ';
+ }
+ $novalnet_comments .= $this->language->get('text_novalnet_account_holder') . $response['invoice_account_holder'] . ' ';
+ $novalnet_comments .= $this->language->get('text_novalnet_iban') . $response['invoice_iban'] . ' ';
+ $novalnet_comments .= $this->language->get('text_novalnet_bic') . $response['invoice_bic'] . ' ';
+ $novalnet_comments .= $this->language->get('text_novalnet_bank') . $response['invoice_bankname'] . ' ' . !empty($response['invoice_bankplace']) . ' ';
+ $amount = ($callback) ? $response['amount']/100 : $response['amount'];
+ $novalnet_comments .= $this->language->get('text_novalnet_amount') . $this->currency->format($amount, $order_info['currency_code'],1). ' ';
+ $novalnet_comments .= $this->language->get('text_payment_reference_any_one') . ' ';
+ $novalnet_comments .= $this->language->get('text_payment_reference') . ' 1: TID ' . $response['tid'] . ' ';
+ $order_no = !empty($response['order_no']) ? $response['order_no'] : $order_info['order_id'];
+ $novalnet_comments .= $this->language->get('text_payment_reference') . ' 2: BNR-' . trim($this->config->get('payment_novalnet_project_id')) . '-' . $order_no . ' ';
+ return $novalnet_comments;
+ }
+
+ /**
+ * Prepare Barzahlen Transaction comments.
+ *
+ * @param $response
+ * @return string
+ */
+ function prepareBarzahlenComments($response) {
+ $storeCounts = 0;
+ foreach ($response as $key => $value) {
+ if (strpos($key, 'nearest_store_street') === 0) {
+ $storeCounts++;
+ }
+ }
+ $novalnet_comments = ($response['cp_due_date'] != '') ? ' ' . $this->language->get('text_novalnet_slip_expiry_date') . date($this->language->get('date_format_short'), strtotime($response['cp_due_date'])) . ' ' : '';
+ $novalnet_comments .= ' ' . $this->language->get('text_nearest_store_details'). ' ';
+ for($i=1; $i<=$storeCounts;$i++) {
+ $novalnet_comments .= ' ' . $response['nearest_store_title_' . $i];
+ $novalnet_comments .= ' ' . $response['nearest_store_street_' . $i];
+ $novalnet_comments .= ' ' . $response['nearest_store_city_' . $i];
+ $novalnet_comments .= ' ' . $response['nearest_store_zipcode_' . $i];
+ $query = $this->db->query("SELECT name FROM " . DB_PREFIX . "country WHERE iso_code_2 = '".$response['nearest_store_country_' . $i]."'");
+ $novalnet_comments .= ' ' . $query->row['name']. ' ';
+ }
+ return $novalnet_comments;
+ }
+
+ /**
+ * Prepare Transaction comments.
+ *
+ * @param $response
+ * @param $payment_name
+ * @return string
+ */
+ public function prepareTransactionComments($response, $payment_name) {
+ $payment_type = $payment_name;
+ $payment_name = 'payment_'.$payment_name;
+ $transaction_comments = '';
+ if(isset($response['payment_id']) && in_array($response['payment_id'],array('40','41'))) {
+ $transaction_comments .= $this->language->get('text_guarantee_payment') . ' ' ;
+ }
+ $transaction_comments .= $this->language->get('text_' . $payment_type . '_title') . ' ';
+ $transaction_comments .= $this->language->get('text_novalnet_TID') . $response['tid'] . ' ';
+ $transaction_comments .= ($response['test_mode'] == 1 || $this->config->get($payment_name . '_testmode') == 1) ? $this->language->get('text_novalnet_test_order') : '';
+ if(isset($response['payment_id']) && $response['payment_id'] == '41' && $response['tid_status'] == 75) {
+ $transaction_comments .= $this->language->get('text_guarantee_pending_text') . ' ' ;
+ }
+ if(isset($response['payment_id']) && $response['payment_id'] == '40' && $response['tid_status'] == 75) {
+ $transaction_comments .= $this->language->get('text_guarantee_pending_sepa_text') . ' ' ;
+ }
+ return $transaction_comments;
+ }
+
+ /**
+ * Get Novalnet recurring profile
+ *
+ * @param none
+ * @return array
+ */
+ public function getNovalnetRecurringProfiles() {
+ $current_date = date('Y-m-d');
+ $sql = "SELECT ore.order_recurring_id, o.order_status_id FROM " . DB_PREFIX . "order_recurring ore
+ INNER JOIN " . DB_PREFIX . "order o ON o.order_id = ore.order_id
+ INNER JOIN " . DB_PREFIX . "novalnet_subscriptions ns ON ns.order_no = o.order_id
+ WHERE ( ns.order_recurring_id = ore.order_recurring_id) AND ( ns.next_subs_cycle = '" . $current_date . "') ORDER BY ore.order_recurring_id DESC";
+ $qry = $this->db->query($sql);
+ $order_recurring = array();
+ foreach ($qry->rows as $profile) {
+ $order_recurring[] = $this->getProfile($profile['order_recurring_id']);
+ }
+ return $order_recurring;
+ }
+
+ /**
+ * Get order recurring profile
+ *
+ * @param $order_recurring_id
+ * @return array
+ */
+ public function getProfile($order_recurring_id) {
+ $qry = $this->db->query("SELECT order_recurring_id, order_id, reference, product_id, product_name, product_quantity, recurring_id, recurring_name, recurring_description, recurring_frequency, recurring_cycle, recurring_duration, recurring_price, trial, trial_frequency, trial_cycle, trial_duration, trial_price, status, date_added FROM " . DB_PREFIX . "order_recurring WHERE order_recurring_id = " . (int)$order_recurring_id);
+ return $qry->row;
+ }
+
+ /**
+ * Get Novalnet recurring order details
+ *
+ * @param $order_recurring_id
+ * @return array
+ */
+ public function getRecurringOrder($order_recurring_id) {
+ $qry = $this->db->query("SELECT order_no, order_recurring_id, tid, next_subs_cycle, trial_details, recurring_details, additional_details, recurring_date_added FROM " . DB_PREFIX . "novalnet_subscriptions WHERE order_recurring_id = '" . (int)$order_recurring_id . "'");
+ return $qry->row;
+ }
+
+ /**
+ * Get Novalnet recurring reference details
+ *
+ * @param $order_id
+ * @return array
+ */
+ public function getReferenceDetails($order_id) {
+ $qry = $this->db->query("SELECT transaction_details FROM " . DB_PREFIX . "novalnet_transactions WHERE order_no = '" . (int)$order_id . "'");
+ return $qry->row;
+ }
+
+ /**
+ * Calculate subscription schedules
+ *
+ * @param $frequency
+ * @param $next_payment
+ * @param $cycle
+ * @return object
+ */
+ public function calculateSubscriptionSchedule($frequency, $next_payment, $cycle) {
+ if ($frequency == 'semi_month') {
+ $day = date_format($next_payment, 'd');
+ $value = 15 - $day;
+ $is_even = false;
+ if ($cycle % 2 == 0) {
+ $is_even = true;
+ }
+ $odd = ($cycle + 1) / 2;
+ $plus_even = ($cycle / 2) + 1;
+ $minus_even = $cycle / 2;
+ if ($day == 1) {
+ $odd = $odd - 1;
+ $plus_even = $plus_even - 1;
+ $day = 16;
+ }
+ if ($day <= 15 && $is_even) {
+ $next_payment->modify('+' . $value . ' day');
+ $next_payment->modify('+' . $minus_even . ' month');
+ } elseif ($day <= 15) {
+ $next_payment->modify('first day of this month');
+ $next_payment->modify('+' . $odd . ' month');
+ } elseif ($day > 15 && $is_even) {
+ $next_payment->modify('first day of this month');
+ $next_payment->modify('+' . $plus_even . ' month');
+ } elseif ($day > 15) {
+ $next_payment->modify('+' . $value . ' day');
+ $next_payment->modify('+' . $odd . ' month');
+ }
+ } else {
+ $next_payment->modify('+' . $cycle . ' ' . $frequency);
+ }
+ return $next_payment;
+ }
+
+ /**
+ * Get the recurring order details
+ *
+ * @param $order_id
+ * @return string
+ */
+ public function getRecuringOrders($order_id) {
+ return $this->db->query("SELECT order_recurring_transaction_id FROM " . DB_PREFIX . "order_recurring_transaction WHERE order_recurring_id = $order_id");
+ }
+
+ /**
+ * Perform CURL process
+ *
+ * @param $parameters
+ * @param $url
+ * @param $payment_call
+ * @return string
+ */
+ public function performPaymentCall($parameters, $url = 'https://payport.novalnet.de/paygate.jsp', $payment_call = TRUE) {
+ if($payment_call) {
+ // Convert array to query string.
+ $parameters = http_build_query($parameters);
+ }
+ $curl_timeout = $this->config->get('novalnet_curl_timeout');
+ // Perform Curl process.
+ // if curl timeout is configured in shop admin, then assign configured values. Otherwise set the static value 240.
+
+ $curl_timeout = (!empty($curl_timeout) && $curl_timeout > 240) ? $curl_timeout : 240;
+
+ $proxy = $this->config->get('novalnet_proxy');
+ $proxy = is_null($proxy) ? '' : trim($proxy);
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $curl_timeout);
+
+ // if proxy value is not empty, then set to curl option
+ if (!empty($proxy)) {
+ curl_setopt($ch, CURLOPT_PROXY, $proxy);
+ }
+ $reponse = curl_exec($ch);
+ curl_close($ch);
+
+ if($payment_call) {
+ parse_str($reponse, $reponse);
+ }
+ // Return the parsed string.
+ return $reponse;
+ }
+
+ /**
+ * To check status of the response
+ *
+ * @param $response
+ * @param $key
+ * @param $status
+ * @return boolean
+ */
+ public function checkResponseStatus($response, $key = 'status' , $status = '100') {
+
+ return !empty($response[$key]) && $response[$key] == $status;
+ }
+
+ /**
+ * To get the Novalnet server URL
+ *
+ * @param $type
+ * @return string
+ */
+ public function getUrl($type)
+ {
+ $payment = array(
+ 'online_transfer' => 'https://payport.novalnet.de/online_transfer_payport',
+ 'paypal' => 'https://payport.novalnet.de/paypal_payport',
+ 'giropay' => 'https://payport.novalnet.de/giropay',
+ 'pci_payport' => 'https://payport.novalnet.de/pci_payport',
+ 'przelewy24' => 'https://payport.novalnet.de/globalbank_transfer',
+ 'nn_infoport' => 'https://payport.novalnet.de/nn_infoport.xml',
+ 'online_bank_transfer' => 'https://payport.novalnet.de/online_banktransfer',
+ );
+ return ($payment[$type]);
+ }
+
+ /**
+ * To get the remote/server IP address
+ *
+ * @param string $type
+ * @return string
+ */
+ public function getIpAddress($type = 'REMOTE_ADDR') {
+ // Check to determine the IP address type
+ if ($type == 'SERVER_ADDR') {
+ if (empty($_SERVER['SERVER_ADDR'])) {
+ // Handled for IIS server
+ $ip_address = gethostbyname($_SERVER['SERVER_NAME']);
+ } else {
+ $ip_address =$this->request->server['SERVER_ADDR'];
+ }
+ } else { // For remote address
+ $ip_address = $this->getRemoteAddress();
+ }
+
+ return $ip_address;
+ }
+
+ /**
+ * To get the remote IP address
+ * @return string
+ */
+ public function getRemoteAddress()
+ {
+ $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
+ foreach ($ip_keys as $key) {
+ if (array_key_exists($key, $_SERVER) === true) {
+ foreach (explode(',', $_SERVER[$key]) as $ip) {
+ // trim for safety measures
+ return trim($ip);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get Basic template details.
+ *
+ * @param $payment_name
+ * @return array
+ */
+ public function getBasicDetails($payment_name) {
+
+ $this->unsetBeforePaymentSession($payment_name);
+ $payment_logo = ($this->config->get('payment_novalnet_payment_logo') == 1) ? $this->language->get('payment_logo') : '';
+ return array(
+ 'payment_logo' => $payment_logo,
+ 'test_mode' => $this->config->get($payment_name . '_testmode'),
+ 'buyer_notification' => trim(strip_tags(html_entity_decode($this->config->get($payment_name . '_buyer_notification'), ENT_QUOTES, 'UTF-8'))),
+ 'continue' => $this->url->link('checkout/success'),
+ 'text_loading' => $this->language->get('text_loading'),
+ );
+ }
+
+ /**
+ * Get shopping type details.
+ *
+ * @param $payment_name
+ * @param $data
+ * @return array
+ */
+ public function getShoppingTypeDetails($payment_name, $data) {
+
+ $payment_type = $payment_name;
+ $payment_name = 'payment_'.$payment_name;
+ $data['shopping_type'] = $shopping_type = $this->config->get($payment_name . '_shopping_type');
+ $data['one_click_process_enabled'] = false;
+ $data['one_click_desc'] = 0;
+ $user_masked_data = array();
+
+ // Check for on click process.
+ if ($shopping_type == 'ONE_CLICK') {
+ $data['one_click_process_enabled'] = true;
+ $data['one_click_desc'] = 1;
+ $data['given_details_style'] = 'display:block';
+ $data['new_details_style'] = 'display:none';
+ $data['customer_oneclick_style'] = 'display:none';
+
+ $user_masked_data = $this->getMaskingDetails($payment_type);
+ if (!empty($user_masked_data)) {
+
+ // Assign masked TID in SESSION.
+
+ $this->session->data[$payment_name]['masked_tid'] = $user_masked_data['tid'];
+ } else {
+ $data['one_click_process_enabled'] = false;
+ $data['given_details_style'] = 'display:none';
+ $data['new_details_style'] = 'display:block';
+ $data['customer_oneclick_style'] = 'display:block';
+ }
+ } else {
+ $data['given_details_style'] = 'display:none';
+ $data['new_details_style'] = 'display:block';
+ $data['customer_oneclick_style'] = 'display:block';
+ }
+
+ if(empty($this->session->data['customer_id'])) {
+ $data['one_click_desc'] = 0;
+ } else if ($payment_name == 'payment_novalnet_cc') {
+ if( $this->config->get('payment_novalnet_cc_3d_enable') == 'yes') {
+ $data['one_click_desc'] = 0;
+ }
+ }
+ $data['user_masked_data'] = $user_masked_data;
+ return $data;
+ }
+
+ /**
+ * Fetch the masking details of user's previous order
+ *
+ * @param $payment_name
+ * @return array
+ */
+ public function getMaskingDetails($payment_name)
+ {
+
+
+ $masked_data = array();
+ if(!empty($this->session->data['customer_id'])) {
+ $query = $this->db->query("SELECT additional_details, one_click_details, tid FROM " . DB_PREFIX . "novalnet_transactions WHERE customer_id = '" . $this->session->data['customer_id'] . "' AND payment_type='" . $payment_name . "' AND create_payment_ref='1' ORDER BY id DESC");
+ // Check for query result.
+ if (! empty($query->row['additional_details'])) {
+ $masked_data = (array)json_decode($query->row['additional_details']);
+ $masked_data['tid'] = $query->row['tid'];
+ }
+ }
+ return $masked_data;
+ }
+
+ /**
+ * Get guarantee details
+ *
+ * @param $payment_name
+ * @param $order_info
+ * @param $data
+ * @return array
+ *
+ */
+ public function getGuaranteeDetails($payment_name, $order_info, $data = array()) {
+
+ $data['enable_guarantee_payment'] = (boolean)$this->config->get($payment_name . '_guarantee_payment_enable');
+ $data['guarantee_payment_error'] = false;
+
+ if ($data['enable_guarantee_payment']) {
+ $data['dob_label'] = $this->language->get('text_guarantee_payment_dob');
+
+ // Default value.
+ $minimum_amount = (int)trim($this->config->get($payment_name . '_guarantee_minimum_order_amount'));
+
+ if ($minimum_amount == '') {
+ $minimum_amount = 999;
+ }
+ $order_amount = (int)$this->getAmountFormat($order_info['total'], $order_info['currency_value']);
+
+ // Billing address.
+ $billing_address = array(
+ 'address_1' => $order_info['payment_address_1'],
+ 'address_2' => $order_info['payment_address_2'],
+ 'postcode' => $order_info['payment_postcode'],
+ 'city' => $order_info['payment_city'],
+ 'country' => $order_info['payment_country']
+ );
+
+ $shipping_address = array(
+ 'address_1' => $order_info['shipping_address_1'],
+ 'address_2' => $order_info['shipping_address_2'],
+ 'postcode' => $order_info['shipping_postcode'],
+ 'city' => $order_info['shipping_city'],
+ 'country' => $order_info['shipping_country']
+ );
+ $data['error_msg'] = '';
+ // Process as guarantee payment.
+ if (!$this->validateAllowedCountries($order_info['payment_iso_code_2'])) {
+ $data['error_msg'] = $this->language->get('error_guarantee_country');
+ }
+ if ($order_info['currency_code'] != 'EUR') {
+ $data['error_msg'] .= $this->language->get('error_guarantee_currency');
+ }
+ if ($billing_address != $shipping_address) {
+ $data['error_msg'] .= $this->language->get('error_guarantee_billing_shipping_address');
+ }
+ if ($order_amount < $minimum_amount) {
+ $data['error_msg'] .= $this->language->get('error_guarantee_minimum_amount') . $minimum_amount . $this->language->get('error_eur');
+
+ }
+
+ if (empty($data['error_msg'])) {
+ $data['customers_dob'] = '';
+ $data['show_fraud_module'] = false;
+ $data['date_format_error'] = $this->language->get('error_telephone_empty');
+ $this->session->data[$payment_name]['guarantee_payment'] = true;
+ $this->session->data[$payment_name]['fraud_module_enabled'] = false;
+ $this->session->data[$payment_name]['guarantee_payment_error'] = false;
+
+ } elseif ($this->config->get($payment_name . '_guarantee_payment_force') == '1') {
+ // Process as normal payment.
+ $data['enable_guarantee_payment'] = $this->session->data[$payment_name]['guarantee_payment'] = $this->session->data[$payment_name]['guarantee_payment_error'] = false;
+ $this->session->data[$payment_name]['fraud_module_enabled'] = true;
+ } else {
+ // Show error on payment field/ checkout.
+ $this->session->data[$payment_name]['guarantee_payment'] = false;
+ $this->session->data[$payment_name]['guarantee_payment_error'] = true;
+ $this->session->data[$payment_name]['fraud_module_enabled'] = $data['show_fraud_module'] = false;
+ $data['guarantee_payment_error'] = false;
+ $data['guarantee_payment_error_text'] = '';
+ }
+ } else {
+ $this->session->data[$payment_name]['guarantee_payment'] = $this->session->data[$payment_name]['guarantee_payment_error'] = false;
+ }
+ $data['guarantee_payment_force'] = $this->config->get($payment_name . '_guarantee_payment_force');
+
+
+ return $data;
+ }
+
+ /**
+ * Convert shop amount into server amount format
+ *
+ * @param $amount
+ *
+ * @param $currency_value
+ *
+ * @return integer
+ */
+ public function getAmountFormat($amount , $currency_value = '')
+ {
+ $amount = (!empty($currency_value)) ? ($amount * $currency_value) : $amount;
+
+ return (sprintf('%0.2f', $amount) * 100);
+ }
+
+ /**
+ * Form One click process parameters
+ *
+ * @param $parameters
+ * @param $payment_name
+ * @param $shopping_type
+ * @param $customer_one_click
+ * @return array
+ */
+ public function formOneClickParams($parameters, $payment_name, $shopping_type, $customer_one_click) {
+
+ if ($shopping_type == 'ONE_CLICK' ) {
+ $payment_type = 'payment_'.$payment_name;
+ if(!empty($this->request->request[$payment_name . '_one_click_shopping'])) {
+
+ $parameters['payment_ref'] = $this->session->data[$payment_type]['masked_tid'];
+
+
+ } elseif($customer_one_click=='True') {
+ $parameters['create_payment_ref'] = '1';
+
+ }
+ }
+
+ return $parameters;
+ }
+
+ /* Check for zero amount booking
+ *
+ * @param $parameters
+ * @param $payment_name
+ * @param $zero_booking
+ */
+ public function zeroBookingParams($parameters, $zero_booking, $payment_name) {
+
+ // Check the zero amount booking.
+ if ($zero_booking == 'ZERO_AMOUNT' && $this->getTariffId(true) == '2') {
+
+ // Assign payment parameters in SESSION.
+ $this->session->data[$payment_name]['payment_params'] = $parameters;
+ $parameters['amount'] = 0;
+ $parameters['create_payment_ref'] = 1;
+ }
+ return $parameters;
+ }
+
+ /**
+ * Assign on-hold to payment parameter
+ *
+ * @param $parameters
+ * @param $amount
+ * @param $payment
+ *
+ * return $parameters
+ */
+ public function getOnholdParameter($parameters, $amount, $payment)
+ {
+ $onhold_limit_amount = trim($this->config->get($payment.'_manual_limit'));
+ if($this->config->get($payment.'_authenticate') == 0) {
+ return $parameters;
+ }
+ if ($this->config->get($payment.'_authenticate') == 1 ) {
+ if (empty($onhold_limit_amount) || ($amount >= $onhold_limit_amount)) {
+ $parameters['on_hold'] = '1';
+ }
+ }
+ return $parameters;
+ }
+
+ /**
+ * Form Guarantee payment parameters
+ *
+ * @param $parameters
+ * @param $payment_name
+ * @return array
+ */
+ public function formGuaranteePaymentParams($parameters, $payment_name) {
+
+ // Load Order information.
+ $order_info = $this->model_checkout_order->getOrder($parameters['order_no']);
+ // Get Guarantee details.
+ $this->getGuaranteeDetails($payment_name, $order_info, array());
+
+ if(!empty($this->session->data[$payment_name]['process_guarantee'])) {
+ $payment_code = ($payment_name == 'payment_novalnet_invoice') ? 'novalnet_invoice_guarantee' : 'novalnet_sepa_guarantee';
+ $parameters['payment_type'] = $this->payment_details[$payment_code]['payment_type'];
+ $parameters['key'] = $this->session->data['nn_payment_key'] = $this->payment_details[$payment_code]['key'];
+ if(empty($this->request->request[$payment_name . '_company'])) {
+ $dob = !empty($this->request->request[$payment_name . '_one_click_shopping']) ? $this->request->request[$payment_name . '_one_click_dob'] : $this->request->request[$payment_name . '_dob'];
+ $parameters['birth_date'] = date('Y-m-d', strtotime($dob));
+ }
+
+ }
+ return $parameters;
+ }
+
+ /**
+ * Validate guarantee process
+ *
+ * @param $payment_name
+ * @return string
+ *
+ */
+ public function validateGuaranteeProcess($payment_name) {
+ $message = '';
+
+ $payment_name = 'payment_'.$payment_name;
+
+ // Validate Age.
+ !empty($this->request->request[$payment_name . '_company'] && !empty($this->session->data[$payment_name]['guarantee_payment'])) ? $this->session->data[$payment_name]['process_guarantee'] = true : $this->session->data[$payment_name]['process_guarantee'] = false;
+ if (!empty($this->session->data[$payment_name]['guarantee_payment']) && empty($this->request->request[$payment_name . '_company'])) {
+ $dob = !empty($this->request->request[$payment_name . '_one_click_shopping']) ? $this->request->request[$payment_name . '_one_click_dob'] : (isset($this->request->request[$payment_name . '_dob']) ? $this->request->request[$payment_name . '_dob'] : '');
+
+ $this->session->data[$payment_name]['process_guarantee'] = true;
+
+ if (empty($dob)) {
+ $message = $this->language->get('error_dob_empty');
+ }elseif (!preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$dob)) {
+ $message = $this->language->get('error_dob_invalid_format');
+ } elseif (time() < strtotime('+18 years', strtotime($dob))) {
+ $message = $this->language->get('error_sepa_age_below_18');
+ }
+ } elseif (!empty($this->session->data[$payment_name]['guarantee_payment_error'])) {
+ $message = $this->language->get('text_guarantee_payment_warning_msg');
+
+ }
+
+ if ($this->config->get($payment_name . '_guarantee_payment_force') == '1' && $message !== '') {
+ $this->session->data[$payment_name]['guarantee_payment'] = $this->session->data[$payment_name]['process_guarantee'] = false;
+ $message = '';
+ }
+
+ return $message;
+ }
+
+ /**
+ * Get the response message
+ *
+ * @param $data
+ *
+ * @return string
+ */
+ public function setResponseMessage($data)
+ {
+ if (isset($data['status_text'])) {
+ return $data['status_text'];
+ } elseif(isset($data['status_desc'])) {
+ return $data['status_desc'];
+ } elseif(isset($data['status_message'])) {
+ return $data['status_message'];
+ } else {
+ return $this->language->get('error_payment_not_successful');
+ }
+ }
+
+ /**
+ * Validate payment fields.
+ *
+ * @param $input_fields
+ * @param $payment_name
+ *
+ * @return string
+ */
+ public function validatePaymentFields($input_fields, $payment_name) {
+
+ foreach($input_fields as $input_field) {
+ $value = trim($this->request->request[$input_field]);
+ if(empty($value)) {
+ return $this->language->get($payment_name . '_payment_details_error');
+ }
+ }
+ return '';
+ }
+
+ /**
+ * Get language code.
+ *
+ * @param $language
+ * @param $upper_case
+ * @return string
+ */
+ public function getLanguageCode($language, $upper_case = true) {
+ $language_code = explode('-', $language);
+ return ($upper_case) ? strtoupper($language_code['0']) : strtolower($language_code);
+ }
+
+ /**
+ * Display payment method based on zone and amount
+ *
+ * @param $payment_name
+ * @param $address
+ * @param $total
+ * @return array
+ */
+ public function showPaymentMethod($payment_name, $address, $total) {
+ $geo_zone_id = (int)$this->config->get('payment_'.$payment_name . '_geo_zone_id');
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . $geo_zone_id . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");
+ $minimum_total = $this->config->get('payment_'.$payment_name . '_total');
+ $status = ($minimum_total > 0 && $minimum_total > $total*100) ? false : ((!$geo_zone_id) ? true : (($query->num_rows) ? true : false ));
+ if ($status) {
+ return array(
+ 'code' => $payment_name,
+ 'title' => $this->language->get('text_title'),
+ 'terms' => '',
+ 'sort_order' => $this->config->get('payment_'.$payment_name . '_sort_order')
+ );
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_cashpayment.php b/catalog/model/extension/payment/novalnet_cashpayment.php
new file mode 100644
index 0000000..2c32c1e
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_cashpayment.php
@@ -0,0 +1,39 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_cc.php b/catalog/model/extension/payment/novalnet_cc.php
new file mode 100644
index 0000000..999483f
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_cc.php
@@ -0,0 +1,52 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+
+ /**
+ * Supports recurring payments.
+ *
+ * @param void
+ * @return boolean
+ */
+ public function recurringPayments()
+ {
+ return true;
+ }
+
+}
diff --git a/catalog/model/extension/payment/novalnet_eps.php b/catalog/model/extension/payment/novalnet_eps.php
new file mode 100644
index 0000000..8c454b1
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_eps.php
@@ -0,0 +1,40 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_giropay.php b/catalog/model/extension/payment/novalnet_giropay.php
new file mode 100644
index 0000000..7580e6c
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_giropay.php
@@ -0,0 +1,40 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_ideal.php b/catalog/model/extension/payment/novalnet_ideal.php
new file mode 100644
index 0000000..39c6017
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_ideal.php
@@ -0,0 +1,40 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_instant_bank_transfer.php b/catalog/model/extension/payment/novalnet_instant_bank_transfer.php
new file mode 100644
index 0000000..8c54eb2
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_instant_bank_transfer.php
@@ -0,0 +1,39 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_invoice.php b/catalog/model/extension/payment/novalnet_invoice.php
new file mode 100644
index 0000000..87e6de3
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_invoice.php
@@ -0,0 +1,59 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ $max_time_status = false;
+ if ($status) {
+ if (!empty($this->session->data['payment_novalnet_invoice_max_time']) && $this->session->data[$this->payment_method . '_max_time'] > time()) {
+ $max_time_status = true;
+ } else {
+ unset($this->session->data['payment_novalnet_invoice_max_time']);
+ }
+
+ if (!$max_time_status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ }
+ return array();
+ }
+
+ /**
+ * Supports recurring payments.
+ *
+ * @return boolean
+ */
+ public function recurringPayments()
+ {
+ return true;
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_online_bank_transfer.php b/catalog/model/extension/payment/novalnet_online_bank_transfer.php
new file mode 100644
index 0000000..ee05c0e
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_online_bank_transfer.php
@@ -0,0 +1,39 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_paypal.php b/catalog/model/extension/payment/novalnet_paypal.php
new file mode 100644
index 0000000..03b687e
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_paypal.php
@@ -0,0 +1,50 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+
+ /**
+ * Supports recurring payments.
+ *
+ * @return boolean
+ */
+ public function recurringPayments()
+ {
+ return true;
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_prepayment.php b/catalog/model/extension/payment/novalnet_prepayment.php
new file mode 100644
index 0000000..735fe2d
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_prepayment.php
@@ -0,0 +1,50 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+
+ /**
+ * Supports recurring payments.
+ *
+ * @return boolean
+ */
+ public function recurringPayments()
+ {
+ return true;
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_przelewy24.php b/catalog/model/extension/payment/novalnet_przelewy24.php
new file mode 100644
index 0000000..23832ab
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_przelewy24.php
@@ -0,0 +1,40 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ if ($status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ return array();
+ }
+}
diff --git a/catalog/model/extension/payment/novalnet_sepa.php b/catalog/model/extension/payment/novalnet_sepa.php
new file mode 100644
index 0000000..bff68fe
--- /dev/null
+++ b/catalog/model/extension/payment/novalnet_sepa.php
@@ -0,0 +1,60 @@
+load->model('extension/payment/novalnet');
+ $status = $this->model_extension_payment_novalnet->getOptionMethod($address, $total, $this->payment_method);
+ $max_time_status = false;
+ if ($status) {
+ if (!empty($this->session->data['novalnet_sepa_max_time']) && $this->session->data['novalnet_sepa_max_time'] > time()) {
+ $max_time_status = true;
+ } else {
+ unset($this->session->data['novalnet_sepa_max_time']);
+ }
+
+ if (!$max_time_status) {
+ return $this->model_extension_payment_novalnet->showPaymentMethod($this->payment_method, $address, $total);
+ }
+ }
+ return array();
+ }
+
+ /**
+ * Supports recurring payments.
+ *
+ * @return boolean
+ */
+ public function recurringPayments()
+ {
+ return true;
+ }
+
+}
diff --git a/catalog/view/javascript/novalnet/novalnet_cc.js b/catalog/view/javascript/novalnet/novalnet_cc.js
new file mode 100644
index 0000000..4d260e1
--- /dev/null
+++ b/catalog/view/javascript/novalnet/novalnet_cc.js
@@ -0,0 +1,139 @@
+/**
+ * Novalnet Credit Card script
+ * By Novalnet AG (https://www.novalnet.de)
+ * Copyright (c) Novalnet AG
+ */
+
+jQuery( document ).ready(function () {
+ var script = "";
+ var nn_Util = 'novalnet_util';
+ if(!document.getElementById(nn_Util)) {
+ script = document.createElement("script");
+ script.type = "text/javascript";
+ script.id = nn_Util;
+ script.src = "https://cdn.novalnet.de/js/v2/NovalnetUtility.js";
+ document.getElementsByTagName("head")[0].appendChild(script);
+ }
+ script.onload = function () {
+ loadCcIframe();
+ }
+ jQuery('#button-confirm').on('click',function(event) {
+ jQuery('.alert-warning').remove();
+ jQuery('#error-msg').hide();
+ jQuery('#button-confirm').attr("disabled", true);
+ if (jQuery('#cc-panhash').val()) {
+ jQuery('#cc-panhash').val('');
+ }
+
+ if(jQuery('#cc-panhash').val() == '' && ((jQuery('#cc-shopping-type').val() == 'ONE_CLICK' && jQuery('#novalnet-cc-one-click-shopping').val() == 0) || jQuery('#cc-shopping-type').val() == 'none' || jQuery('#cc-shopping-type').val() == 'ZERO_AMOUNT')){
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ NovalnetUtility.getPanHash();
+ } else {
+ confirm();
+ }
+ });
+
+ jQuery('#nn-new-card-link').bind('click', function(){
+ jQuery('#cc-masking-form').hide();
+ jQuery('#nn-cc-iframe').show();
+ jQuery('#novalnet-cc-one-click-shopping').val('0');
+ loadCcIframe();
+ });
+
+ jQuery('#nn-given-card-link').bind('click',function(){
+ jQuery('#cc-masking-form').show();
+ jQuery('#nn-cc-iframe').hide();
+ jQuery('#novalnet-cc-one-click-shopping').val(1);
+ jQuery('#given_card_details').hide();
+ });
+});
+
+function loadCcIframe() {
+ if((jQuery('#cc-shopping-type').val() == 'ONE_CLICK' && jQuery('#novalnet-cc-one-click-shopping').val() == 0 ) || jQuery('#cc-shopping-type').val() == 'none' || jQuery('#cc-shopping-type').val() == 'ZERO_AMOUNT'){
+
+ NovalnetUtility.setClientKey(jQuery('#nn-client-key').val());
+
+ var configurationObject = {
+ callback : {
+
+ // Called once the pan_hash (temp. token) created successfully.
+ on_success: function (data) {
+ jQuery('#cc-panhash').val(data ['hash'] );
+ jQuery('#cc-unique-id').val(data['unique_id']);
+ jQuery('#cc-do-redirect').val(data['do_redirect']);
+ confirm();
+ return true;
+ },
+ on_error: function (data) {
+ if ( undefined !== data['error_message'] ) {
+ jQuery('#button-confirm').attr("disabled", false);
+ confirm();
+ return false;
+ }
+ },
+ on_show_overlay: function (data) {
+ document.getElementById('novalnet-iframe').classList.add("novalnet-challenge-window-overlay");
+ },
+ on_hide_overlay: function (data) {
+ document.getElementById('novalnet-iframe').classList.remove("novalnet-challenge-window-overlay");
+ }
+
+ },
+ iframe: {
+ id: "novalnet-iframe",
+ inline: 0,
+ style: {
+ container: jQuery('#cc-iframe-standard-css-text').val(),
+ input: jQuery('#cc-iframe-standard-input').val(),
+ label: jQuery('#cc-iframe-standard-label').val(),
+ },
+ text: {
+ error: jQuery('#text-cc-card-details-error').val(),
+ card_holder : {
+ label: jQuery('#text-cc-holder').val(),
+ place_holder: jQuery('#text-cc-holder-placeholder').val(),
+ error: "Please enter the valid card holder name"
+ },
+ card_number : {
+ label: jQuery('#text-cc-number').val(),
+ place_holder: jQuery('#text-cc-number-placeholder').val(),
+ error: "Please enter the valid card number"
+ },
+ expiry_date : {
+ label: jQuery('#text-cc-expiry-date').val(),
+ place_holder: jQuery('#text-cc-date-placeholder').val(),
+ error: "Please enter the valid expiry month / year in the given format"
+ },
+ cvc : {
+ label: jQuery('#text-cc-cvc').val(),
+ place_holder: jQuery('#text-cc-cvc-placeholder').val(),
+ error: "Please enter the valid CVC/CVV/CID"
+ }
+ }
+ },
+ customer: {
+ first_name: jQuery("#nn-first-name").val(),
+ last_name: jQuery("#nn-last-name").val(),
+ email: jQuery("#nn-email").val(),
+ billing: {
+ street: jQuery("#nn-billing-street").val(),
+ city: jQuery("#nn-billing-city").val(),
+ zip: jQuery("#nn-billing-zip").val(),
+ country_code: jQuery("#nn-billing-country-code").val()
+ },
+ },
+ transaction: {
+ amount: jQuery("#transaction-amount").val(),
+ currency: jQuery("#shop-currency").val(),
+ test_mode: jQuery("#nn-test-mode").val(),
+ enforce_3d: jQuery("#nn-enforce-3d").val()
+ },
+ custom: {
+ lang : jQuery('#shop-lang').val(),
+ }
+ };
+ // Create the Credit Card form
+ NovalnetUtility.createCreditCardForm(configurationObject);
+ }
+}
diff --git a/catalog/view/javascript/novalnet/novalnet_sepa.js b/catalog/view/javascript/novalnet/novalnet_sepa.js
new file mode 100644
index 0000000..65ba30b
--- /dev/null
+++ b/catalog/view/javascript/novalnet/novalnet_sepa.js
@@ -0,0 +1,32 @@
+/**
+ * Novalnet Direct Debit SEPA script
+ * By Novalnet AG (https://www.novalnet.de)
+ * Copyright (c) Novalnet AG
+ */
+
+$(document).ready(function(){
+ $("#button-confirm").click(function(){
+ var account_holder = remove_space(jQuery('#input-novalnet-sepa-holder').val());
+ var iban = jQuery.trim(jQuery('#input-novalnet-sepa-account-no').val()).replace(/[^a-z0-9]+/gi, '');
+ var one_click = remove_space(jQuery('#novalnet-sepa-one-click-shopping').val());
+ if ((account_holder.length == 0 || iban.length == 0) && one_click == 0) {
+ alert(jQuery('#novalnet-sepa-account-error').val());
+ return false;
+ }
+
+ });
+});
+
+function sepa_validation(event) {
+ var keycode = ('which' in event) ? event.which : event.keyCode;
+ var reg = /^(?:[A-Za-z0-9]+$)/;
+ if (event.target.id == 'input-novalnet-sepa-holder')
+ reg = /[^0-9\[\]\/\\#,+@!^()$~%'"=:;<>{}\_\|*?`]/g;
+ if (event.target.id == 'input-novalnet-sepa-account-no')
+ reg = /^(?:[A-Za-z0-9]+$)/;
+ return (reg.test(String.fromCharCode(keycode)) || keycode === 0 || keycode === 8) ? true : false;
+}
+
+function remove_space(input_val) {
+ return input_val.trim();
+}
diff --git a/catalog/view/theme/default/stylesheet/novalnet.css b/catalog/view/theme/default/stylesheet/novalnet.css
new file mode 100644
index 0000000..b6e8424
--- /dev/null
+++ b/catalog/view/theme/default/stylesheet/novalnet.css
@@ -0,0 +1,30 @@
+.loader {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ z-index: 9999;
+ background: url('../../../../../image/payment/novalnet/nn_loader.gif') 50% 50% no-repeat;
+}
+
+
+.novalnet-challenge-window-overlay {
+position: fixed;
+width: 100%;
+height: 100% ! important;
+top: 0;
+left: 0;
+right: 0;
+bottom: 0;
+background-color: rgba(0,0,0,0.5);
+z-index: 2;
+cursor: pointer;
+}
+
+
+@keyframes novalnet-blinker {
+100% {
+opacity: 0;
+}
+}
\ No newline at end of file
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_cashpayment.twig b/catalog/view/theme/default/template/extension/payment/novalnet_cashpayment.twig
new file mode 100644
index 0000000..5a9ecaa
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_cashpayment.twig
@@ -0,0 +1,56 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_barzahlen_payment_description }}
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_cc.twig b/catalog/view/theme/default/template/extension/payment/novalnet_cc.twig
new file mode 100644
index 0000000..70f1190
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_cc.twig
@@ -0,0 +1,171 @@
+
+
+
+ {{ text_title }} {{ payment_logo }} {{ amex_logo }} {{ maestro_logo }}
+ {% if nn_enforce_3d != "0" %}
+ {{ text_payment_description }}
+ {% else %}
+ {{ text_direct_payment_description }}
+ {% endif %}
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+ {% if oneclick =='ZERO_AMOUNT' %}
+ {{ zero_amount_desc }}
+ {% endif %}
+ {% if buyer_notification is not empty %}
+
{{ buyer_notification }}
+ {% endif %}
+
+
+
+ {% set one_click = 0 %}
+
+ {% if one_click_process_enabled is not empty %}
+ {% set one_click = 1 %}
+
+ {% endif %}
+
+
+
+ {% if one_click_process_enabled is not empty %}
+
+ {{ novalnet_cc_given_card_details }}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if oneclick =='ONE_CLICK' and one_click_desc == 1 %}
+
   
{{ save_card_details }}
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_eps.twig b/catalog/view/theme/default/template/extension/payment/novalnet_eps.twig
new file mode 100644
index 0000000..bfa0dae
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_eps.twig
@@ -0,0 +1,51 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_giropay.twig b/catalog/view/theme/default/template/extension/payment/novalnet_giropay.twig
new file mode 100644
index 0000000..c4db302
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_giropay.twig
@@ -0,0 +1,53 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_ideal.twig b/catalog/view/theme/default/template/extension/payment/novalnet_ideal.twig
new file mode 100644
index 0000000..d313650
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_ideal.twig
@@ -0,0 +1,52 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_instant_bank_transfer.twig b/catalog/view/theme/default/template/extension/payment/novalnet_instant_bank_transfer.twig
new file mode 100644
index 0000000..ed05e04
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_instant_bank_transfer.twig
@@ -0,0 +1,52 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_invoice.twig b/catalog/view/theme/default/template/extension/payment/novalnet_invoice.twig
new file mode 100644
index 0000000..ac71a10
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_invoice.twig
@@ -0,0 +1,100 @@
+
+
+
+ {% if guarantee_payment_force == false %}
+ {{error_msg}}
+ {% endif %}
+ {{ text_title }} {{ payment_logo }}
+ {{ text_payment_description }}
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
+ {% if enable_guarantee_payment and guarantee_payment_error == false and company is empty and error_msg is empty %}
+
+ {% elseif guarantee_payment_error %}
+
{{ guarantee_payment_error_text }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_online_bank_transfer.twig b/catalog/view/theme/default/template/extension/payment/novalnet_online_bank_transfer.twig
new file mode 100644
index 0000000..e587c50
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_online_bank_transfer.twig
@@ -0,0 +1,52 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_paypal.twig b/catalog/view/theme/default/template/extension/payment/novalnet_paypal.twig
new file mode 100644
index 0000000..e25cc01
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_paypal.twig
@@ -0,0 +1,137 @@
+
+
+ {{ text_title }} {{ payment_logo }}
+
+ {% if one_click_process_enabled is not empty %}
+ {% set display_style = 'display:block;' %}
+ {% else %}
+ {% set display_style = 'display:none;' %}
+ {% endif %}
+
+
{{ text_guarantee_payment_reference_transaction }}
+
+ {% if one_click_process_enabled is not empty %}
+ {% set one_click = 'display:none;' %}
+ {% else %}
+ {% set one_click = 'display:block;' %}
+ {% endif %}
+
+
{{ text_paypal_payment_description }}
+
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if oneclick =='ZERO_AMOUNT' %}
+ {{ zero_amount_desc }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+
{{ buyer_notification }}
+ {% endif %}
+
+
+
+ {% set one_click = 0 %}
+
+ {% if one_click_process_enabled is not empty %}
+
+ {% set one_click = 1 %}
+
+
+
+ {{ novalnet_paypal_new_payment_details }}
+
+
+
+
+ {% endif %}
+
+ {% if oneclick =='ONE_CLICK' and one_click_desc == 1 %}
+    {{ save_card_details }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_prepayment.twig b/catalog/view/theme/default/template/extension/payment/novalnet_prepayment.twig
new file mode 100644
index 0000000..8b25379
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_prepayment.twig
@@ -0,0 +1,54 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_payment_description }}
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_przelewy24.twig b/catalog/view/theme/default/template/extension/payment/novalnet_przelewy24.twig
new file mode 100644
index 0000000..1c3e866
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_przelewy24.twig
@@ -0,0 +1,52 @@
+{{ text_title }} {{ payment_logo }}
+{{ text_paypal_payment_description }}
+
+
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+ {{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/payment/novalnet_sepa.twig b/catalog/view/theme/default/template/extension/payment/novalnet_sepa.twig
new file mode 100644
index 0000000..277bdd5
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/payment/novalnet_sepa.twig
@@ -0,0 +1,282 @@
+
+
+ {% if guarantee_payment_force == false %}
+ {{error_msg}}
+ {% endif %}
+ {{ text_title }} {{ payment_logo }}
+ {{ text_payment_description }}
+ {% if test_mode != "0" %}
+ {{ text_test_mode_description }}
+ {% endif %}
+
+ {% if one_click =='ZERO_AMOUNT' and enable_guarantee_payment is empty %}
+
+ {{ zero_amount_desc }}
+ {% endif %}
+
+ {% if buyer_notification is not empty %}
+
{{ buyer_notification }}
+ {% endif %}
+
+
+
+
+
+
+ {% if one_click_process_enabled is not empty %}
+
+ {% else %}
+
+ {% endif %}
+
+
+
+
+
+ {% if one_click_process_enabled is not empty %}
+
+ {{ novalnet_sepa_given_account_details }}
+
+ {% endif %}
+
+
+
+ {% if enable_guarantee_payment and guarantee_payment_error == false and company is empty and error_msg is empty %}
+
+ {% elseif guarantee_payment_error %}
+
{{ guarantee_payment_error_text }}
+ {% endif %}
+
+ {% if show_fraud_module and enable_guarantee_payment == false %}
+
+ {% endif %}
+ {% if one_click =='ONE_CLICK' and one_click_desc == 1 %}
+
+    {{ save_card_details }}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
diff --git a/catalog/view/theme/default/template/extension/recurring/novalnet_recurring.twig b/catalog/view/theme/default/template/extension/recurring/novalnet_recurring.twig
new file mode 100644
index 0000000..c852bc7
--- /dev/null
+++ b/catalog/view/theme/default/template/extension/recurring/novalnet_recurring.twig
@@ -0,0 +1,54 @@
+{% if next_subs_cycle != '0000-00-00' %}
+ {{ text_next_charging_date }} {{ next_subs_cycle }}
+
+{% endif %}
+
+{{ text_recurring_orders }}
+
+
+
+
+ {{ text_novalnet_order_no }}
+ {{ text_novalnet_TID }}
+ {{ text_novalnet_amount }}
+ {{ text_payment_method }}
+ {{ text_transaction_details }}
+
+
+
+ {% for value in recurring_details %}
+
+ {{ value.order_no }}
+ {{ value.tid }}
+ {{ value.amount }}
+ {{ payment_method }}
+ {{ value.transaction_details }}
+
+ {% endfor %}
+
+
+
+
+
diff --git a/changelog.txt b/changelog.txt
new file mode 100644
index 0000000..42ca4eb
--- /dev/null
+++ b/changelog.txt
@@ -0,0 +1,54 @@
+*** Changelog ***
+
+= 11.5.0 - 2024.07.08 =
+* New - Implemented Online Bank Transfer payment
+* Fix - Compatibility for OpenCart 3.0.3.9
+
+= 11.4.0 - 2021.08.03 =
+*New - Implemented enforce 3D secure payment for countries outside EU
+*New - Implemented Payment duration for Prepayment
+*Fix - For guarantee payments, handled email notification to the end customers on payment confirmation
+*Enhanced - Callback has been optimized as per the new testcase
+*Removed - PIN by callback and PIN by SMS for Direct Debit SEPA and Invoice payment methods
+*Removed - BIC field for Direct Debit SEPA
+*Removed - Proxy server configuration
+*Removed - Gateway timeout configuration
+*Removed - Referrer Id configuration
+
+= 11.3.1 - 2021.03.23 =
+* Fix - Chrome Samesite Cookies
+* Enhanced - Barzahlen payment name and logo
+* Enhanced - Callback has been optimized as per the new testcase
+* Removed - href links for the payment logo
+
+= 11.3.0 - 2020.08.14 =
+* New - Force 3D secure process has been implemented as per predefined filters and settings in the Novalnet Merchant Administration portal
+* New - Custom checkout overlay for Barzahlen
+* New - Notify end customer for storing Card / Account information
+* New - Guaranteed payment pending status has been implemented
+* New - Customized the payment logo
+* Enhanced - Guaranteed payment minimum amount reduced to 9,99 EUR
+* Enhanced - Implemented new encryption method for redirect payments
+* Enhanced - Auto configuration call perform via cURL method
+* Enhanced - On-hold transaction configuration has been implemented for Credit Card, Direct Debit SEPA, Direct Debit SEPA with payment guarantee, Invoice, Invoice with payment guarantee and PayPal
+* Enhanced - Novalnet bank details will be displayed in invoice for on-hold transactions in Invoice, Invoice with payment guarantee and Prepayment
+* Enhanced - Novalnet Merchant Administration portal link has been updated in shop admin
+* Enhanced - Callback has been optimized as per the new testcase
+* Enhanced - Adjusted the payment plugin for IPV6 condition
+* Removed - Autofill and Payment refill for payment data
+* Removed - BIC field for Direct Debit SEPA
+* Removed - Payment reference configuration for Invoice / Prepayment
+* Removed - Transaction reference in payments
+
+= 11.2.1 - 2017.11.22 =
+* Enhanced - Dynamic IP control applied through domain instead of static IP in vendor script. Actual IP of Novalnet will be extracted in real time from the domain
+
+= 11.2.0 - 2017.11.02 =
+* New - Implemented Barzahlen payment method
+* Enhanced - Merchant Administration Portal link has been updated in shop admin
+* Enhanced - Optimized vendor script validation
+* Removed - Refund with account details from shop admin
+* Removed - Enable debug mode configuration in Merchant script management
+
+= 11.1.0 - 2017.04.27 =
+New release
diff --git a/image/payment/novalnet/nn_loader.gif b/image/payment/novalnet/nn_loader.gif
new file mode 100644
index 0000000..cf70c2e
Binary files /dev/null and b/image/payment/novalnet/nn_loader.gif differ
diff --git a/image/payment/novalnet/novalnet.png b/image/payment/novalnet/novalnet.png
new file mode 100644
index 0000000..6e9b8b9
Binary files /dev/null and b/image/payment/novalnet/novalnet.png differ
diff --git a/image/payment/novalnet/novalnet_amex.png b/image/payment/novalnet/novalnet_amex.png
new file mode 100644
index 0000000..bbf54e1
Binary files /dev/null and b/image/payment/novalnet/novalnet_amex.png differ
diff --git a/image/payment/novalnet/novalnet_banktransfer.png b/image/payment/novalnet/novalnet_banktransfer.png
new file mode 100644
index 0000000..e42c46e
Binary files /dev/null and b/image/payment/novalnet/novalnet_banktransfer.png differ
diff --git a/image/payment/novalnet/novalnet_cashpayment.png b/image/payment/novalnet/novalnet_cashpayment.png
new file mode 100644
index 0000000..053fcf3
Binary files /dev/null and b/image/payment/novalnet/novalnet_cashpayment.png differ
diff --git a/image/payment/novalnet/novalnet_cc.png b/image/payment/novalnet/novalnet_cc.png
new file mode 100644
index 0000000..e085d07
Binary files /dev/null and b/image/payment/novalnet/novalnet_cc.png differ
diff --git a/image/payment/novalnet/novalnet_cc_mastercard.png b/image/payment/novalnet/novalnet_cc_mastercard.png
new file mode 100644
index 0000000..a95a96d
Binary files /dev/null and b/image/payment/novalnet/novalnet_cc_mastercard.png differ
diff --git a/image/payment/novalnet/novalnet_eps.png b/image/payment/novalnet/novalnet_eps.png
new file mode 100644
index 0000000..02875ae
Binary files /dev/null and b/image/payment/novalnet/novalnet_eps.png differ
diff --git a/image/payment/novalnet/novalnet_giropay.png b/image/payment/novalnet/novalnet_giropay.png
new file mode 100644
index 0000000..5bcd509
Binary files /dev/null and b/image/payment/novalnet/novalnet_giropay.png differ
diff --git a/image/payment/novalnet/novalnet_ideal.png b/image/payment/novalnet/novalnet_ideal.png
new file mode 100644
index 0000000..9d08251
Binary files /dev/null and b/image/payment/novalnet/novalnet_ideal.png differ
diff --git a/image/payment/novalnet/novalnet_invoice.png b/image/payment/novalnet/novalnet_invoice.png
new file mode 100644
index 0000000..ca3f1c8
Binary files /dev/null and b/image/payment/novalnet/novalnet_invoice.png differ
diff --git a/image/payment/novalnet/novalnet_maestro.png b/image/payment/novalnet/novalnet_maestro.png
new file mode 100644
index 0000000..834af79
Binary files /dev/null and b/image/payment/novalnet/novalnet_maestro.png differ
diff --git a/image/payment/novalnet/novalnet_onlinebanktransfer.png b/image/payment/novalnet/novalnet_onlinebanktransfer.png
new file mode 100644
index 0000000..357743b
Binary files /dev/null and b/image/payment/novalnet/novalnet_onlinebanktransfer.png differ
diff --git a/image/payment/novalnet/novalnet_paypal.png b/image/payment/novalnet/novalnet_paypal.png
new file mode 100644
index 0000000..9defac5
Binary files /dev/null and b/image/payment/novalnet/novalnet_paypal.png differ
diff --git a/image/payment/novalnet/novalnet_prepayment.png b/image/payment/novalnet/novalnet_prepayment.png
new file mode 100644
index 0000000..9104281
Binary files /dev/null and b/image/payment/novalnet/novalnet_prepayment.png differ
diff --git a/image/payment/novalnet/novalnet_przelewy24.png b/image/payment/novalnet/novalnet_przelewy24.png
new file mode 100644
index 0000000..331d7b3
Binary files /dev/null and b/image/payment/novalnet/novalnet_przelewy24.png differ
diff --git a/image/payment/novalnet/novalnet_sepa.png b/image/payment/novalnet/novalnet_sepa.png
new file mode 100644
index 0000000..7daf3ca
Binary files /dev/null and b/image/payment/novalnet/novalnet_sepa.png differ