From c71e3a77ec8328ceaf0b9eba7ee434df0961ae63 Mon Sep 17 00:00:00 2001 From: Novalnet Date: Wed, 10 Nov 2021 14:08:44 +0100 Subject: [PATCH] first commit --- extras/novalnet_callback.php | 856 ++++++++++++++++ images/icons/novalnet/novalnet_PayPal.png | Bin 0 -> 1976 bytes .../icons/novalnet/novalnet_cashpayment.png | Bin 0 -> 2418 bytes images/icons/novalnet/novalnet_cc_amex.png | Bin 0 -> 1186 bytes images/icons/novalnet/novalnet_cc_maestro.png | Bin 0 -> 1050 bytes images/icons/novalnet/novalnet_cc_master.png | Bin 0 -> 1061 bytes images/icons/novalnet/novalnet_cc_visa.png | Bin 0 -> 2908 bytes images/icons/novalnet/novalnet_eps.png | Bin 0 -> 1064 bytes images/icons/novalnet/novalnet_giropay.png | Bin 0 -> 1223 bytes images/icons/novalnet/novalnet_ideal.png | Bin 0 -> 1481 bytes .../icons/novalnet/novalnet_instantbank.png | Bin 0 -> 952 bytes images/icons/novalnet/novalnet_invoice.png | Bin 0 -> 613 bytes .../icons/novalnet/novalnet_postfinance.png | Bin 0 -> 1986 bytes .../novalnet/novalnet_postfinance_card.png | Bin 0 -> 2351 bytes images/icons/novalnet/novalnet_prepayment.png | Bin 0 -> 978 bytes images/icons/novalnet/novalnet_przelewy24.png | Bin 0 -> 2180 bytes images/icons/novalnet/novalnet_sepa.png | Bin 0 -> 1152 bytes includes/classes/class.novalnetutil.php | 935 ++++++++++++++++++ includes/ext/novalnet/css/novalnet.css | 18 + includes/ext/novalnet/install/install.sql | 20 + includes/ext/novalnet/js/novalnet_admin.js | 116 +++ includes/ext/novalnet/js/novalnet_api.js | 127 +++ includes/ext/novalnet/js/novalnet_cc.js | 115 +++ .../js/novalnet_instalment_invoice.js | 63 ++ includes/ext/novalnet/js/novalnet_sepa.js | 101 ++ includes/ext/novalnet/novalnet_admin.php | 49 + .../english/modules/payment/novalnet.php | 136 +++ .../modules/payment/novalnet_PayPal.php | 51 + .../modules/payment/novalnet_banktransfer.php | 41 + .../modules/payment/novalnet_cashpayment.php | 50 + .../english/modules/payment/novalnet_cc.php | 65 ++ .../modules/payment/novalnet_config.php | 57 ++ .../english/modules/payment/novalnet_eps.php | 42 + .../modules/payment/novalnet_giropay.php | 42 + .../payment/novalnet_guarantee_invoice.php | 53 + .../payment/novalnet_guarantee_sepa.php | 58 ++ .../modules/payment/novalnet_ideal.php | 42 + .../payment/novalnet_instalment_invoice.php | 60 ++ .../payment/novalnet_instalment_sepa.php | 61 ++ .../modules/payment/novalnet_invoice.php | 55 ++ .../modules/payment/novalnet_postfinance.php | 45 + .../payment/novalnet_postfinance_card.php | 44 + .../modules/payment/novalnet_prepayment.php | 44 + .../modules/payment/novalnet_przelewy24.php | 45 + .../english/modules/payment/novalnet_sepa.php | 53 + .../german/modules/payment/novalnet.php | 135 +++ .../modules/payment/novalnet_PayPal.php | 52 + .../modules/payment/novalnet_banktransfer.php | 42 + .../modules/payment/novalnet_cashpayment.php | 50 + .../german/modules/payment/novalnet_cc.php | 65 ++ .../modules/payment/novalnet_config.php | 60 ++ .../german/modules/payment/novalnet_eps.php | 42 + .../modules/payment/novalnet_giropay.php | 42 + .../payment/novalnet_guarantee_invoice.php | 53 + .../payment/novalnet_guarantee_sepa.php | 58 ++ .../german/modules/payment/novalnet_ideal.php | 42 + .../payment/novalnet_instalment_invoice.php | 60 ++ .../payment/novalnet_instalment_sepa.php | 61 ++ .../modules/payment/novalnet_invoice.php | 54 + .../modules/payment/novalnet_postfinance.php | 45 + .../payment/novalnet_postfinance_card.php | 44 + .../modules/payment/novalnet_prepayment.php | 44 + .../modules/payment/novalnet_przelewy24.php | 45 + .../german/modules/payment/novalnet_sepa.php | 54 + includes/modules/payment/novalnet_PayPal.php | 278 ++++++ .../modules/payment/novalnet_banktransfer.php | 272 +++++ .../modules/payment/novalnet_cashpayment.php | 265 +++++ includes/modules/payment/novalnet_cc.php | 358 +++++++ includes/modules/payment/novalnet_config.php | 165 ++++ includes/modules/payment/novalnet_eps.php | 275 ++++++ includes/modules/payment/novalnet_giropay.php | 267 +++++ .../payment/novalnet_guarantee_invoice.php | 311 ++++++ .../payment/novalnet_guarantee_sepa.php | 312 ++++++ includes/modules/payment/novalnet_ideal.php | 269 +++++ .../payment/novalnet_instalment_invoice.php | 370 +++++++ .../payment/novalnet_instalment_sepa.php | 364 +++++++ includes/modules/payment/novalnet_invoice.php | 266 +++++ .../modules/payment/novalnet_postfinance.php | 271 +++++ .../payment/novalnet_postfinance_card.php | 273 +++++ .../modules/payment/novalnet_prepayment.php | 262 +++++ .../modules/payment/novalnet_przelewy24.php | 274 +++++ includes/modules/payment/novalnet_sepa.php | 277 ++++++ novalnet_autoconfig.php | 68 ++ 83 files changed, 9689 insertions(+) create mode 100644 extras/novalnet_callback.php create mode 100644 images/icons/novalnet/novalnet_PayPal.png create mode 100644 images/icons/novalnet/novalnet_cashpayment.png create mode 100644 images/icons/novalnet/novalnet_cc_amex.png create mode 100644 images/icons/novalnet/novalnet_cc_maestro.png create mode 100644 images/icons/novalnet/novalnet_cc_master.png create mode 100644 images/icons/novalnet/novalnet_cc_visa.png create mode 100644 images/icons/novalnet/novalnet_eps.png create mode 100644 images/icons/novalnet/novalnet_giropay.png create mode 100644 images/icons/novalnet/novalnet_ideal.png create mode 100644 images/icons/novalnet/novalnet_instantbank.png create mode 100644 images/icons/novalnet/novalnet_invoice.png create mode 100644 images/icons/novalnet/novalnet_postfinance.png create mode 100644 images/icons/novalnet/novalnet_postfinance_card.png create mode 100644 images/icons/novalnet/novalnet_prepayment.png create mode 100644 images/icons/novalnet/novalnet_przelewy24.png create mode 100644 images/icons/novalnet/novalnet_sepa.png create mode 100644 includes/classes/class.novalnetutil.php create mode 100644 includes/ext/novalnet/css/novalnet.css create mode 100644 includes/ext/novalnet/install/install.sql create mode 100644 includes/ext/novalnet/js/novalnet_admin.js create mode 100644 includes/ext/novalnet/js/novalnet_api.js create mode 100644 includes/ext/novalnet/js/novalnet_cc.js create mode 100644 includes/ext/novalnet/js/novalnet_instalment_invoice.js create mode 100644 includes/ext/novalnet/js/novalnet_sepa.js create mode 100644 includes/ext/novalnet/novalnet_admin.php create mode 100644 includes/languages/english/modules/payment/novalnet.php create mode 100644 includes/languages/english/modules/payment/novalnet_PayPal.php create mode 100644 includes/languages/english/modules/payment/novalnet_banktransfer.php create mode 100644 includes/languages/english/modules/payment/novalnet_cashpayment.php create mode 100644 includes/languages/english/modules/payment/novalnet_cc.php create mode 100644 includes/languages/english/modules/payment/novalnet_config.php create mode 100644 includes/languages/english/modules/payment/novalnet_eps.php create mode 100644 includes/languages/english/modules/payment/novalnet_giropay.php create mode 100644 includes/languages/english/modules/payment/novalnet_guarantee_invoice.php create mode 100644 includes/languages/english/modules/payment/novalnet_guarantee_sepa.php create mode 100644 includes/languages/english/modules/payment/novalnet_ideal.php create mode 100644 includes/languages/english/modules/payment/novalnet_instalment_invoice.php create mode 100644 includes/languages/english/modules/payment/novalnet_instalment_sepa.php create mode 100644 includes/languages/english/modules/payment/novalnet_invoice.php create mode 100644 includes/languages/english/modules/payment/novalnet_postfinance.php create mode 100644 includes/languages/english/modules/payment/novalnet_postfinance_card.php create mode 100644 includes/languages/english/modules/payment/novalnet_prepayment.php create mode 100644 includes/languages/english/modules/payment/novalnet_przelewy24.php create mode 100644 includes/languages/english/modules/payment/novalnet_sepa.php create mode 100644 includes/languages/german/modules/payment/novalnet.php create mode 100644 includes/languages/german/modules/payment/novalnet_PayPal.php create mode 100644 includes/languages/german/modules/payment/novalnet_banktransfer.php create mode 100644 includes/languages/german/modules/payment/novalnet_cashpayment.php create mode 100644 includes/languages/german/modules/payment/novalnet_cc.php create mode 100644 includes/languages/german/modules/payment/novalnet_config.php create mode 100644 includes/languages/german/modules/payment/novalnet_eps.php create mode 100644 includes/languages/german/modules/payment/novalnet_giropay.php create mode 100644 includes/languages/german/modules/payment/novalnet_guarantee_invoice.php create mode 100644 includes/languages/german/modules/payment/novalnet_guarantee_sepa.php create mode 100644 includes/languages/german/modules/payment/novalnet_ideal.php create mode 100644 includes/languages/german/modules/payment/novalnet_instalment_invoice.php create mode 100644 includes/languages/german/modules/payment/novalnet_instalment_sepa.php create mode 100644 includes/languages/german/modules/payment/novalnet_invoice.php create mode 100644 includes/languages/german/modules/payment/novalnet_postfinance.php create mode 100644 includes/languages/german/modules/payment/novalnet_postfinance_card.php create mode 100644 includes/languages/german/modules/payment/novalnet_prepayment.php create mode 100644 includes/languages/german/modules/payment/novalnet_przelewy24.php create mode 100644 includes/languages/german/modules/payment/novalnet_sepa.php create mode 100644 includes/modules/payment/novalnet_PayPal.php create mode 100644 includes/modules/payment/novalnet_banktransfer.php create mode 100644 includes/modules/payment/novalnet_cashpayment.php create mode 100644 includes/modules/payment/novalnet_cc.php create mode 100644 includes/modules/payment/novalnet_config.php create mode 100644 includes/modules/payment/novalnet_eps.php create mode 100644 includes/modules/payment/novalnet_giropay.php create mode 100644 includes/modules/payment/novalnet_guarantee_invoice.php create mode 100644 includes/modules/payment/novalnet_guarantee_sepa.php create mode 100644 includes/modules/payment/novalnet_ideal.php create mode 100644 includes/modules/payment/novalnet_instalment_invoice.php create mode 100644 includes/modules/payment/novalnet_instalment_sepa.php create mode 100644 includes/modules/payment/novalnet_invoice.php create mode 100644 includes/modules/payment/novalnet_postfinance.php create mode 100644 includes/modules/payment/novalnet_postfinance_card.php create mode 100644 includes/modules/payment/novalnet_prepayment.php create mode 100644 includes/modules/payment/novalnet_przelewy24.php create mode 100644 includes/modules/payment/novalnet_sepa.php create mode 100644 novalnet_autoconfig.php diff --git a/extras/novalnet_callback.php b/extras/novalnet_callback.php new file mode 100644 index 0000000..7e3c9d1 --- /dev/null +++ b/extras/novalnet_callback.php @@ -0,0 +1,856 @@ + array('CREDITCARD','CREDITCARD_BOOKBACK','CREDITCARD_CHARGEBACK','CREDIT_ENTRY_CREDITCARD','DEBT_COLLECTION_CREDITCARD','TRANSACTION_CANCELLATION'), + 'novalnet_sepa' => array('DIRECT_DEBIT_SEPA','RETURN_DEBIT_SEPA','CREDIT_ENTRY_SEPA','DEBT_COLLECTION_SEPA','REFUND_BY_BANK_TRANSFER_EU','TRANSACTION_CANCELLATION'), + 'novalnet_guarantee_sepa' => array('RETURN_DEBIT_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_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_banktransfer' => array('ONLINE_TRANSFER','REFUND_BY_BANK_TRANSFER_EU','ONLINE_TRANSFER_CREDIT','REVERSAL','CREDIT_ENTRY_DE','DEBT_COLLECTION_DE'), + 'novalnet_PayPal' => array('PAYPAL','PAYPAL_BOOKBACK','TRANSACTION_CANCELLATION'), + 'novalnet_prepayment' => array('INVOICE_START','INVOICE_CREDIT','REFUND_BY_BANK_TRANSFER_EU'), + 'novalnet_invoice' => array('INVOICE_START','INVOICE_CREDIT','REFUND_BY_BANK_TRANSFER_EU','TRANSACTION_CANCELLATION','CREDIT_ENTRY_DE','DEBT_COLLECTION_DE'), + 'novalnet_guarantee_invoice' => array('GUARANTEED_INVOICE','GUARANTEED_INVOICE_BOOKBACK','REFUND_BY_BANK_TRANSFER_EU','TRANSACTION_CANCELLATION'), + 'novalnet_przelewy24' => array('PRZELEWY24','PRZELEWY24_REFUND'), + 'novalnet_cashpayment' => array('CASHPAYMENT','CASHPAYMENT_REFUND','CASHPAYMENT_CREDIT'), + 'novalnet_instalment_invoice' => array('INSTALMENT_INVOICE','INSTALMENT_INVOICE_BOOKBACK','TRANSACTION_CANCELLATION'), + 'novalnet_instalment_sepa' => array('INSTALMENT_DIRECT_DEBIT_SEPA','INSTALMENT_SEPA_BOOKBACK', + 'TRANSACTION_CANCELLATION'), + 'novalnet_postfinance' => array('POSTFINANCE', 'POSTFINANCE_REFUND'), + 'novalnet_postfinance_card' => array('POSTFINANCE_CARD', 'POSTFINANCE_REFUND'), + ); + + /** + * Mandatory Parameters. + * + * @var array + */ + protected $required_params = array( + 'vendor_id', + 'status', + 'payment_type', + 'tid_status', + 'tid', + ); + + /** + * Novalnet success codes. + * + * @var array + */ + protected $success_code = array( + 'PAYPAL' => array('100', '90','85'), + 'INVOICE_START' => array('100','91'), + 'INSTALMENT_INVOICE' => array('100','91','75'), + 'GUARANTEED_INVOICE' => array('100','91','75'), + 'CREDITCARD' => array('100','98'), + 'DIRECT_DEBIT_SEPA' => array('100','99'), + 'INSTALMENT_DIRECT_DEBIT_SEPA' => array('100','99','75'), + 'GUARANTEED_DIRECT_DEBIT_SEPA' => array('100','99','75'), + 'ONLINE_TRANSFER' => array('100'), + 'ONLINE_TRANSFER_CREDIT' => array('100'), + 'GIROPAY' => array('100'), + 'IDEAL' => array('100'), + 'EPS' => array('100'), + 'PRZELEWY24' => array('100','86'), + 'CASHPAYMENT' => array('100'), + 'POSTFINANCE_CARD' => array('100','83'), + 'POSTFINANCE' => array('100','83'), + ); + + /** + * construct + * + * @return none + */ + public function __construct($request) + { + $this->validate_ipaddress(); + + $this->server_request = $this->validate_server_request($request); + + $this->order_reference = $this->get_order_reference(); + include_once( DIR_FS_CATALOG . DIR_WS_INCLUDES .'languages/' . $this->order_reference['nn_order_lang'] . '/modules/payment/novalnet.php'); + $this->transaction_cancellation($this->order_reference); + + $payment_type_level = $this->get_payment_type(); + + $this->formatted_amount = sprintf('%0.2f', $this->server_request['amount'] / 100) .' '. $this->server_request['currency']; + + switch($payment_type_level) { + case 0: + $this->zero_level_process(); + break; + case 1: + $this->first_level_process(); + break; + case 2: + $this->second_level_process(); + break; + default: + $this->display_message('Novalnet Callbackscript received. Payment type ( ' . $this->server_request['payment_type'] . ' ) is not applicable for this process!'); + break; + } + $this->display_message(($this->server_request['tid_status'] != '100' || $this->server_request['status'] != '100') ? 'Novalnet callback received. Status is not valid.' : 'Novalnet callback received. Callback Script executed already.'); + } + + /** + * Payment types of Level 0 - Initial level payments processing + * + * @return none + */ + public function zero_level_process() + { + global $db; + + if (in_array($this->server_request['payment_type'], $this->payments, true ) && $this->server_request['status'] == '100' && in_array($this->server_request['tid_status'], $this->success_code[$this->server_request['payment_type']], true)) { + if (in_array( $this->server_request['payment_type'], array('INSTALMENT_INVOICE', 'INSTALMENT_DIRECT_DEBIT_SEPA')) && isset($this->server_request['instalment_billing']) && $this->server_request['instalment_billing'] == '1' && $this->server_request['tid_status'] == '100' && $this->server_request['status'] == '100' ) { + $comments = NovalnetUtil::formPaymentComments($this->server_request['tid'], $this->server_request['test_mode']); + $amount = sprintf('%0.2f', $this->server_request['amount'] / 100); + if ($this->server_request['payment_type'] == 'INSTALMENT_INVOICE') { + $comments .= PHP_EOL . PHP_EOL . NovalnetUtil::formInvoicePrepaymentComments($this->server_request, $amount); + $comments .= PHP_EOL . NovalnetUtil::novalnetReferenceComments($this->server_request['order_no'],$this->server_request, $this->order_reference['payment_type']); + } + if ($this->server_request['payment_type'] == 'INSTALMENT_DIRECT_DEBIT_SEPA') { + $comments .= PHP_EOL.PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_INSTALMENT_SEPA_INFO, $amount, $this->server_request['currency']); + } + + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_INFO; + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_PROCESSED . (!empty($this->server_request['instalment_cycles_executed']) ? $this->server_request['instalment_cycles_executed'] : '') ; + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_DUE . (isset($this->server_request['due_instalment_cycles']) ? $this->server_request['due_instalment_cycles'] : ''); + + $amount = (!empty($this->server_request['instalment_cycle_amount']) ? $this->server_request['instalment_cycle_amount'] : $this->server_request['amount']); + $amount = sprintf('%0.2f', $amount / 100); + + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_NXT_AMOUNT .$amount. ' '.$this->server_request['currency'] ; + + $instalment = unserialize($this->order_reference['instalment_details']); + + $instalment[$this->server_request['instalment_cycles_executed']] = array( + 'amount' => ($this->server_request['amount']) ? sprintf('%0.2f', $this->server_request['amount'] / 100) : '', + 'nextCycle' => ($this->server_request['next_instalment_date']) ? $this->server_request['next_instalment_date'] : '', + 'paidDate' => ($this->server_request['tid_status'] == '100') ? date('Y-m-d') : '', + 'status' => 'Paid', + 'reference' => !empty($this->server_request['tid']) ? $this->server_request['tid'] : '' + ); + + $instalment_details = serialize($instalment); + + $param['gateway_status'] = $this->server_request['tid_status']; + $param['instalment_details'] = serialize($instalment); + zen_db_perform('novalnet_transaction_detail', $param, "update", "tid='" . $this->server_request['shop_tid'] . "'"); + + $payment_name = strtoupper($this->order_reference['payment_type']); + + $order_status = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_' . $payment_name . '_ORDER_STATUS_ID')); + + $db->Execute("UPDATE " . TABLE_ORDERS . " SET orders_status= " . $order_status . " where orders_id=" . $this->order_reference['order_no']); + + $this->update_final_comments($this->server_request, $comments, $order_status, $this->order_reference['order_no']); + } + $this->update_pending_payments(); + + // After execution. + $this->display_message('Novalnet Callbackscript received. Payment type ( ' . $this->server_request['payment_type'] . ' ) is not applicable for this process!'); + } + } + + /** + * Payment types of Level 1 - Chargeback payments processing + * + * @return none + */ + public function first_level_process() + { + if (in_array( $this->server_request['payment_type'], $this->chargebacks, true ) && $this->server_request['tid_status'] == '100' && $this->server_request['status'] == '100') { + $comments = MODULE_PAYMENT_NOVALNET_CALLBACK_CHARGEBACK; + if ( in_array( $this->server_request['payment_type'], array( 'PAYPAL_BOOKBACK', 'CREDITCARD_BOOKBACK', 'REFUND_BY_BANK_TRANSFER_EU', 'PRZELEWY24_REFUND', 'POSTFINANCE_REFUND', 'CASHPAYMENT_REFUND', 'GUARANTEED_INVOICE_BOOKBACK', 'GUARANTEED_SEPA_BOOKBACK', 'INSTALMENT_SEPA_BOOKBACK', 'INSTALMENT_INVOICE_BOOKBACK' ), true ) ) { + $comments = MODULE_PAYMENT_NOVALNET_CALLBACK_BOOKBACK; + } + $callback_comments = sprintf($comments, $this->server_request['shop_tid'], $this->formatted_amount, date('Y-m-d H:i:s'), $this->server_request['tid']) . PHP_EOL; + //Update the comments , order id and status id in Novalnet table + $this->update_final_comments($this->server_request, $callback_comments, $this->order_reference['order_current_status'], $this->order_reference['order_no']); + } + } + + /** + * Payment types of Level 2 - Credit entry and collection payments processing + * + * @return none + */ + public function second_level_process() + { + if (in_array($this->server_request['payment_type'], $this->collections) && $this->server_request['tid_status'] == '100' && $this->server_request['status'] == '100') { + + if (in_array($this->server_request['payment_type'], array('INVOICE_CREDIT', 'ONLINE_TRANSFER_CREDIT', 'CASHPAYMENT_CREDIT'))) { + + if ($this->order_reference['order_paid_amount'] < $this->order_reference['order_total_amount']) { + $callback_comments = sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CREDIT, $this->server_request['shop_tid'], $this->formatted_amount, date('Y-m-d H:i:s'), $this->server_request['tid']); + + $callback_status_id = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_'.strtoupper($this->order_reference['payment_type']).'_ORDER_STATUS_ID')); + + $total_amount = $this->order_reference['order_paid_amount'] + $this->server_request['amount']; + if ($this->order_reference['order_total_amount'] <= $total_amount) { + $callback_status_id = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_'.strtoupper($this->order_reference['payment_type']).'_CALLBACK_STATUS_ID')); + $callback_comments .= ($this->order_reference['order_total_amount'] < $total_amount) ? ' Paid amount is greater than Order amount.' : ''; + } + + //Update callback order status due to full payment + zen_db_perform(TABLE_ORDERS, array( + 'orders_status' => $callback_status_id + ), 'update', 'orders_id="' . $this->order_reference['order_no'] . '"'); + + $this->update_final_comments($this->server_request, $callback_comments, $callback_status_id, $this->order_reference['order_no'], $total_amount); + } + $this->display_message('Novalnet callback script executed already'); + } else { + $callback_comments = sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CREDIT, $this->server_request['shop_tid'], $this->formatted_amount, date('Y-m-d H:i:s'), $this->server_request['tid']); + + $callback_status_id = $this->order_reference['order_current_status']; + + $this->update_final_comments($this->server_request, $callback_comments, $callback_status_id, $this->order_reference['order_no']); + } + $this->display_message('Novalnet Callbackscript received. Payment type ( ' . $this->server_request['payment_type'] . ' ) is not applicable for this process!' ); + } + } + + /** + * Update pending payments. + * + * @return none + */ + public function update_pending_payments() + { + global $db; + if (isset($this->order_reference['gateway_status'] ) && $this->order_reference['gateway_status'] != 100 ) { + $comments = $callback_comments = ''; + $param = array(); + $paymentName = strtoupper($this->order_reference['payment_type']); + + if ($this->server_request['payment_type'] =='PAYPAL' && in_array($this->order_reference['gateway_status'] , array(85, 90))){ + if ($this->order_reference['gateway_status'] == 85 && $this->server_request['tid_status'] == 90) { + $order_status = MODULE_PAYMENT_NOVALNET_PAYPAL_PENDING_ORDER_STATUS_ID; + $callback_comments .= PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_HOLD_TO_PENDING, $this->server_request['shop_tid'], date('Y-m-d H:i:s') ) . PHP_EOL; + } elseif (in_array($this->order_reference['gateway_status'], array(85, 90)) && $this->server_request['tid_status'] == 100) { + $order_status = MODULE_PAYMENT_NOVALNET_PAYPAL_ORDER_STATUS_ID; + $callback_comments = PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CONFIRM, date('Y-m-d H:i:s')) . PHP_EOL; + } + $order_status = NovalnetUtil::checkDefaultOrderStatus($order_status); + + $db->Execute("UPDATE novalnet_transaction_detail SET gateway_status= " . $this->server_request['tid_status'] . " where order_no=" . $this->order_reference['order_no']); + + $db->Execute("UPDATE " . TABLE_ORDERS . " SET orders_status= " . $order_status . " where orders_id=" . $this->order_reference['order_no']); + + $this->update_final_comments($this->server_request, $callback_comments, $order_status, $this->order_reference['order_no']); + } elseif (in_array($this->server_request['payment_type'], array('PAYPAL', 'PRZELEWY24')) && $this->server_request['tid_status'] == 100) { + if ($this->order_reference['callback_amount'] <= 0 ) { + $callback_comments = PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_EXECUTE, $this->server_request['shop_tid'], $this->formatted_amount, date('Y-m-d H:i:s')) . PHP_EOL; + + $order_status = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_' . $paymentName . '_ORDER_STATUS_ID')); + + $db->Execute("UPDATE novalnet_transaction_detail SET gateway_status= " . $this->server_request['tid_status'] . " where order_no=" . $this->order_reference['order_no']); + + $db->Execute("UPDATE " . TABLE_ORDERS . " SET orders_status= " . $order_status . " where orders_id=" . $this->order_reference['order_no']); + + $this->update_final_comments($this->server_request, $callback_comments, $order_status, $this->order_reference['order_no']); + } + $this->display_message('Novalnet Callbackscript received. Order already Paid'); + + } else if (in_array($this->server_request['payment_type'], array('POSTFINANCE','POSTFINANCE_CARD')) && $this->order_reference['gateway_status'] == 83 && $this->server_request['tid_status'] == 100 && $this->server_request['status'] == 100) { + $callback_comments = PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CONFIRM, date('Y-m-d H:i:s')) . PHP_EOL; + + $order_status = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_' . $paymentName . '_ORDER_STATUS_ID')); + + $db->Execute("UPDATE novalnet_transaction_detail SET gateway_status= " . $this->server_request['tid_status'] . " where order_no=" . $this->order_reference['order_no']); + + $db->Execute("UPDATE " . TABLE_ORDERS . " SET orders_status= " . $order_status . " where orders_id=" . $this->order_reference['order_no']); + + $this->update_final_comments($this->server_request, $callback_comments, $order_status, $this->order_reference['order_no']); + } elseif ($this->server_request['payment_type'] == 'PRZELEWY24' && $this->server_request['tid_status'] != '86') { + //Handle Przelewy cancel + $message = $this->updatePrzelewyCancelcomments($this->order_reference); + $this->display_message($message); + } elseif (in_array($this->server_request['payment_type'], $this->payments)) { + if (in_array($this->server_request['tid_status'], array(99, 91) ) && $this->order_reference['gateway_status'] == 75) { + $order_status = NovalnetUtil::checkDefaultOrderStatus(MODULE_PAYMENT_NOVALNET_ONHOLD_ORDER_COMPLETE_STATUS_ID); + $callback_comments .= sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_PENDING_TO_HOLD, $this->server_request['shop_tid'], date('Y-m-d H:i:s') ); + $callback_comments .= NovalnetUtil::formPaymentComments($this->server_request['shop_tid'], $this->server_request['test_mode']); + + if (in_array($this->server_request['payment_type'], array('INSTALMENT_INVOICE', 'GUARANTEED_INVOICE'))) { + $amount = sprintf('%0.2f', $this->server_request['amount'] / 100); + $callback_comments .= PHP_EOL . PHP_EOL . NovalnetUtil::formInvoicePrepaymentComments($this->server_request, $amount); + + $callback_comments .= NovalnetUtil::novalnetReferenceComments($this->server_request['order_no'],$this->server_request, $this->order_reference['payment_type']); + } + + } elseif($this->server_request['tid_status'] == 100 && in_array($this->order_reference['gateway_status'], array(75,98,91,99))) { + $order_status = NovalnetUtil::checkDefaultOrderStatus(constant('MODULE_PAYMENT_'.$paymentName.'_ORDER_STATUS_ID')); + $comments = ''; + if (in_array($this->server_request['payment_type'],array('INSTALMENT_INVOICE', 'INSTALMENT_DIRECT_DEBIT_SEPA', 'GUARANTEED_INVOICE', 'GUARANTEED_DIRECT_DEBIT_SEPA'))) { + $comments .= NovalnetUtil::formPaymentComments($this->server_request['shop_tid'], $this->server_request['test_mode']); + + if (in_array($this->server_request['payment_type'], array ('INSTALMENT_INVOICE', 'GUARANTEED_INVOICE'))) { + $amount = sprintf('%0.2f', $this->server_request['amount'] / 100); + $comments .= PHP_EOL . PHP_EOL . NovalnetUtil::formInvoicePrepaymentComments($this->server_request, $amount); + + $comments .= NovalnetUtil::novalnetReferenceComments($this->server_request['order_no'],$this->server_request, $this->order_reference['payment_type']); + } + if(in_array($this->server_request['payment_type'],array('INSTALMENT_INVOICE', 'INSTALMENT_DIRECT_DEBIT_SEPA'))) { + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_INFO; + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_PROCESSED . (!empty($this->server_request['instalment_cycles_executed']) ? $this->server_request['instalment_cycles_executed'] : '') ; + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_DUE . (isset($this->server_request['due_instalment_cycles']) ? $this->server_request['due_instalment_cycles'] : ''); + $amount = (!empty($this->server_request['instalment_cycle_amount']) ? $this->server_request['instalment_cycle_amount'] : $this->server_request['amount']); + $amount = sprintf('%0.2f', $amount / 100); + + $comments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_NXT_AMOUNT .$amount. ' '.$this->server_request['currency'] ; + if ($future_instalment = $this->server_request['future_instalment_dates']) { + $future_instalments = explode('|', $future_instalment); + foreach ($future_instalments as $future_instalment) { + $cycle = strtok($future_instalment, "-"); + $cycle_date = explode('-', $future_instalment, 2); + $instalment_details[$cycle] = [ + 'amount' => ($this->server_request['amount']) ? sprintf('%0.2f', $this->server_request['amount'] / 100) : '', + 'nextCycle' => $cycle_date[1], + 'paidDate' => ($cycle == 1) ? date('Y-m-d') : '', + 'status' => ($cycle == 1) ? 'Paid' : 'Pending', + 'reference' => ($cycle == 1) ? $this->server_request['shop_tid'] : '' + ]; + } + } + $instalment_details = serialize($instalment_details); + $param['gateway_status'] = $this->server_request['tid_status']; + $param['instalment_details'] = $instalment_details; + zen_db_perform('novalnet_transaction_detail', $param, "update", "tid='" . $this->server_request['shop_tid'] . "'"); + } + } + $callback_comments .= $comments . PHP_EOL. sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CONFIRM, date('Y-m-d H:i:s')) . PHP_EOL; + } + + if(in_array($this->server_request['payment_type'],array('INSTALMENT_INVOICE', 'GUARANTEED_INVOICE', 'INVOICE_START')) && in_array($this->order_reference['gateway_status'], array(75, 91)) && $this->server_request['tid_status'] == 100) { + $this->sentPaymentConfirmationMail($callback_comments); + } + + $param ['gateway_status'] = $this->server_request['tid_status']; + $order_status = NovalnetUtil::checkDefaultOrderStatus($order_status); + + zen_db_perform('novalnet_transaction_detail', $param, "update", "tid='" . $this->server_request['shop_tid'] . "'"); + // Update the order status in shop + zen_db_perform(TABLE_ORDERS, array( + 'orders_status' => $order_status + ), 'update', 'orders_id="' . $this->order_reference['order_no'] . '"'); + // To update order details in shop + $this->update_callback_comments(array( + 'order_no' => $this->order_reference['order_no'], + 'orders_status_id' => $order_status, + 'comments' => $callback_comments + )); + // Send notification mail to Merchant + $this->send_notify_mail(array( + 'comments' => $callback_comments, + 'order_no' => $this->order_reference['order_no'], + )); + } else { + + $this->display_message('Novalnet Callbackscript received Payment type ( ' . $this->server_request['payment_type'] . ' ) is not applicable for this process!'); + } + } + } + + /** + * Validate ip address + * + * @return none + */ + public function validate_ipaddress() + { + $remote_ip = zen_get_ip_address(); + + $remote_ip = (filter_var($remote_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || empty($remote_ip)) ? '127.0.0.1' : $remote_ip; + + $get_host_name = gethostbyname('pay-nn.de'); + if (empty($get_host_name)) { + $this->display_message('Novalnet HOST IP missing'); + } + + if ($remote_ip != $get_host_name && MODULE_PAYMENT_NOVALNET_CALLBACK_TEST_MODE == 'False') { + $this->display_message("Novalnet callback received. Unauthorised access from the IP " . $remote_ip); + } + } + + /** + * Validate callback request param + * + * @param $request array + * + * @return none + */ + public function validate_server_request($request) + { + $this->required_params[] = $shop_tid = $this->get_required_tid($request); + + // Validate the callback mandatory request parameters. + $this->validate_required_fields($this->required_params, $request); + + if (!empty($request['payment_type']) && !in_array($request['payment_type'], array_merge($this->payments, $this->chargebacks, $this->collections, $this->cancellation), true)) { + $this->display_message('Novalnet callback received. Payment type ( ' . $request['payment_type'] . ' ) is mismatched!'); + } + + $request['shop_tid'] = $request[$shop_tid]; + + return $request; + } + + /** + * Validate request param + * + * @param $required_params array + * @param $request array + * + * @return none + */ + public function validate_required_fields($required_params, $request) { + + foreach ($required_params as $params) { + if (empty($request[$params])) { + $this->display_message( "Required param ( $params ) missing!" ); + } elseif (in_array($params, array( 'tid', 'tid_payment', 'instalment_tid' ), true ) && ! preg_match( '/^\d{17}$/', $request[ $params])) { + $this->display_message('Novalnet callback received. Invalid TID [ ' . $request[$params] . ' ] for Order.'); + } + } + } + + /** + * Get tid details + * + * @param $request array + * + * @return integer + */ + public function get_required_tid( $request ) { + + $shop_tid = 'tid'; + if (in_array($request['payment_type'], array_merge( $this->chargebacks, $this->collections ), true ) ) { // Collection Payments or Chargeback Payments + if (in_array($request['payment_type'], array('INSTALMENT_INVOICE_BOOKBACK', 'INSTALMENT_SEPA_BOOKBACK' ))) { + $shop_tid = 'instalment_tid'; + } else { + $shop_tid = 'tid_payment'; + } + } + if (in_array($request['payment_type'], array( 'INSTALMENT_DIRECT_DEBIT_SEPA', 'INSTALMENT_INVOICE' )) && $request['instalment_billing'] == '1' ) { // Instalment Payments + $shop_tid = 'instalment_tid'; + } + return $shop_tid; + } + + /** + * Get order details + * + * @return array + */ + public function get_order_reference() { + global $db; + + if (in_array($this->server_request['payment_type'], array_merge($this->payments,$this->cancellation))) { + $tid = zen_db_input($this->server_request['shop_tid']); + } elseif (in_array($this->server_request['payment_type'], $this->chargebacks)) { + $tid = zen_db_input($this->server_request['shop_tid']); + } elseif (in_array($this->server_request['payment_type'], $this->collections)) { + $tid = zen_db_input($this->server_request['tid_payment']); + } + if (!empty($this->server_request['order_no'])){ + $db_val = $db->Execute("SELECT order_no, amount, payment_id, payment_type,language,callback_amount,gateway_status,instalment_details from novalnet_transaction_detail where order_no = '" .$this->server_request['order_no']. "'"); + } else { + $db_val = $db->Execute("SELECT order_no, amount, payment_id, payment_type,language,callback_amount,gateway_status,instalment_details from novalnet_transaction_detail where tid = '" .$tid. "'"); + } + $db_val = $db_val->fields; + $db_val['tid'] = $this->server_request['shop_tid']; + + if (!empty($db_val)) { + if(is_array($this->payment_groups[$db_val['payment_type']])) { + if (!in_array($this->server_request['payment_type'], $this->payment_groups[$db_val['payment_type']])) { + $this->display_message('Novalnet callback received. Payment Type [' . $this->server_request['payment_type'] . '] is not valid.'); + } + } + + $order_no = (!empty($this->server_request['order_no']) ? $this->server_request['order_no'] : ''); + if (!empty($order_no)) { + $order_detail = $db->Execute('SELECT orders_id FROM '.TABLE_ORDERS.' WHERE orders_id = '.zen_db_input($order_no)); + if ( empty($order_detail) ) { + $this->sentCriticalMail(); + } + } + + if (!empty($order_no) && $order_no != $db_val['order_no']) { + $this->display_message('Novalnet callback received. Order Number is not valid.'); + } + + $db_val['nn_order_lang'] = $db_val['language']; + $db_val['order_current_status'] = $this->getOrderCurrentStatus($db_val['order_no']); + + if (in_array($db_val['payment_type'], array('novalnet_invoice', 'novalnet_prepayment'))) { + $db_val['callback_script_status'] = constant('MODULE_PAYMENT_' . strtoupper($db_val['payment_type']) . '_CALLBACK_STATUS_ID'); + } + $db_val['order_total_amount'] = $db_val['amount']; + $db_val['order_paid_amount'] = isset($db_val['callback_amount']) ? $db_val['callback_amount'] : 0; + + } else { + $this->display_message('Novalnet callback script order number not valid'); + } + + return $db_val; + } + + /** + * Get orders_status from the orders table on shop database + * + * @param $order_id integer + * + * @return array + */ + function getOrderCurrentStatus($order_id = '') + { + global $db; + $db_val = $db->Execute("select orders_status from " . TABLE_ORDERS . " where orders_id = '" . $order_id . "'"); + return NovalnetUtil::checkDefaultOrderStatus($db_val->fields['orders_status']); + } + + /** + * Update Przelewy24 cancel status + * + * @param $nntrans_history array + * + * @return string + */ + function updatePrzelewyCancelcomments($nntrans_history) + { + $nncapture_params = $this->server_request(); + $callback_status_id = NovalnetUtil::checkDefaultOrderStatus($nntrans_history['callback_script_status']); + + // Assign przelewy24 payment status + zen_db_perform(TABLE_ORDERS, array( + 'orders_status' => $callback_status_id + ), 'update', 'orders_id="' . $nntrans_history['order_no'] . '"'); + + // Form failure comments + $comments = !empty($nncapture_params['status_text']) ? PHP_EOL . $nncapture_params['status_text'] : (!empty($nncapture_params['status_desc']) ? PHP_EOL . $nncapture_params['status_desc'] : (!empty($nncapture_params['status_message']) ? PHP_EOL . $nncapture_params['status_message'] : '')); + $callback_comments = sprintf('The transaction has been canceled due to: %s', $comments); + + $this->update_callback_comments(array('order_no' => $nntrans_history['order_no'], 'comments' => $callback_comments, + 'orders_status_id' => $callback_status_id)); + + return $callback_comments; + } + + /** + * Handle transaction_cancellation process + * + * $param $order_reference array + * + * @return none + */ + function transaction_cancellation($order_reference) + { + if ($this->server_request['payment_type'] == 'TRANSACTION_CANCELLATION') { + + // To form the callback comments + $callback_comments = sprintf(MODULE_PAYMENT_NOVALNET_CALLBACK_CANCEL, date('Y-m-d H:i:s')); + + $param ['gateway_status'] = $this->server_request['tid_status']; + zen_db_perform('novalnet_transaction_detail', $param, "update", "tid='" . $this->server_request['shop_tid'] . "'"); + $order_status = NovalnetUtil::checkDefaultOrderStatus(MODULE_PAYMENT_NOVALNET_ONHOLD_ORDER_CANCELLED_STATUS_ID); + //Update callback order status due to full payment + zen_db_perform(TABLE_ORDERS, array( + 'orders_status' => $order_status + ), 'update', 'orders_id="' . $order_reference['order_no'] . '"'); + + // To update order details in shop + $this->update_callback_comments(array( + 'order_no' => $order_reference['order_no'], + 'orders_status_id' => $order_status, + 'comments' => $callback_comments + )); + // Send notification mail to Merchant + $this->send_notify_mail(array( + 'comments' => $callback_comments, + 'order_no' => $order_reference['order_no'], + )); + } + } + + /** + * Get given payment_type level for process + * + * @return integer + */ + function get_payment_type() + { + if (in_array($this->server_request['payment_type'], $this->payments)) + return 0; + if (in_array($this->server_request['payment_type'], $this->chargebacks)) + return 1; + if (in_array($this->server_request['payment_type'], $this->collections)) + return 2; + } + + /** + * update callback comments + * + * @param $server_request + * @param $comments + * @param $callback_status_id + * @param $order_id + * @param $total_amount + * + * @return none + */ + function update_final_comments($server_request, $comments, $callback_status_id, $order_id, $total_amount = '') + { + $this->update_callback_comments(array('order_no' => $order_id, 'comments' => $comments, 'orders_status_id' => $callback_status_id)); + $this->logCallbackProcess($server_request, $order_id, $total_amount); + $this->send_notify_mail(array('comments' => $comments, 'order_no' => $order_id)); + } + + /** + * Log callback process in novalnet_transaction_detail table + * @param $datas + * @param $order_no + * @param $total_amount + * + * @return none + */ + function logCallbackProcess($datas, $order_no, $total_amount) + { + global $db; + if (!empty($datas['amount'])) { + $datas['amount'] = !empty($total_amount) ? $total_amount : $datas['amount']; + $db->Execute("UPDATE novalnet_transaction_detail SET callback_amount= " . $datas['amount'] . " where order_no=$order_no"); + } + } + + /** + * Update Callback comments in orders_status_history table + * @param $datas + * + * @return none + */ + function update_callback_comments($datas) + { + global $db; + $comments = ((!empty($datas['comments'])) ? $datas['comments'] : ''); + $db->Execute("INSERT INTO " . TABLE_ORDERS_STATUS_HISTORY . " (orders_id, orders_status_id, date_added, customer_notified, comments) VALUES ('" . $datas['order_no'] . "', '" . $datas['orders_status_id'] . "', NOW(), '1','$comments')"); + } + + /** + * Send notify mail + * + * @param $message + * + * @return none + */ + function send_notify_mail($message) { + // Check for callback notification + if (MODULE_PAYMENT_NOVALNET_CALLBACK_MAIL_SEND == 'True' && NovalnetUtil::validateEmail(strip_tags(MODULE_PAYMENT_NOVALNET_CALLBACK_MAIL_TO))) { + // Get E-mail to address + $email_to = ((strip_tags(MODULE_PAYMENT_NOVALNET_CALLBACK_MAIL_TO) != '') ? strip_tags(MODULE_PAYMENT_NOVALNET_CALLBACK_MAIL_TO) : STORE_OWNER_EMAIL_ADDRESS); + + // Get E-mail to name + $email_to_name = (strpos($email_to,',')) ? '' : STORE_OWNER; + + // Assign Mail subject + $email_subject = 'Novalnet Callback script notification - '. STORE_NAME; + + if ($email_to != '') { + // Send E-mail + zen_mail($email_to_name ,$email_to, $email_subject, $message['comments'] , STORE_NAME, EMAIL_FROM); + echo 'Mail sent!
'; + } else { + echo 'Mail not sent!'; + } + } + + // Display message + $this->display_message($message['comments']); + } + + /** + * sent payment confirmation mail to customer. + * + * @param $comments string + * + * @return string + */ + function sentPaymentConfirmationMail($comments) + { + $customer_details = $this->get_customer_details($this->server_request['customer_id']); + $customer_name = $customer_details['customers_firstname'] . ' ' . $customer_details['customers_lastname']; + $email_subject = sprintf(MODULE_PAYMENT_GUARANTEE_PAYMENT_MAIL_SUBJECT, $this->order_reference['order_no'],STORE_NAME); + $email_content = 'Dear Mr./Ms./Mrs. '. $customer_name .'

' . MODULE_PAYMENT_GUARANTEE_PAYMENT_MAIL_MESSAGE.'

Payment Information:

' . nl2br($comments) .'
'; + + zen_mail($customer_name, $customer_details['customers_email_address'], $email_subject, str_replace(PHP_EOL,'
',$email_content), STORE_NAME, EMAIL_FROM); + } + + /** + * Get customer details from customer table. + * + * @param $customer_id interger + * + * @return array + */ + public static function get_customer_details($customer_id) + { + global $db; + $customer_value = $db->Execute("SELECT customers_firstname, customers_lastname, customers_email_address FROM " . TABLE_CUSTOMERS . " WHERE customers_id='" . $customer_id ."'"); + return $customer_value->fields; + } + + /** + * Send critical mail + * + * @return none + */ + public static function sentCriticalMail() + { + $subject = 'Critical error on shop system '.STORE_NAME.': order not found for TID: ' . $this->server_request['shop_tid']; + $message = "Dear Technic team,

Please evaluate this transaction and contact our payment module team at Novalnet.

"; + $message .= 'Merchant ID: ' . $this->server_request['vendor_id'] . '
'; + $message .= 'Project ID: ' . $this->server_request['product_id'] . '
'; + $message .= 'TID: ' . $this->server_request['shop_tid'] . '
'; + $message .= 'TID status: ' . $this->server_request['tid_status'] . '
'; + $message .= 'Order no: ' . $this->server_request['order_no'] . '
'; + $message .= 'Payment type: ' . $this->server_request['payment_type'] . '
'; + $message .= 'E-mail: ' . $this->server_request['email'] . '
'; + + $message .= '

Regards,
Novalnet Team'; + + zen_mail('Technic team' ,'technic@novalnet.de', $subject, $message ,STORE_NAME, EMAIL_FROM); + } + + /** + * Display message + * + * @param $message string + * @param $order_no integer + * + * @return none + */ + public static function display_message($message, $order_no = '') + { + echo !empty($order_no) ? 'message='. $message.'&order_no='.$order_no : 'message='.$message; + exit; + } +} +?> diff --git a/images/icons/novalnet/novalnet_PayPal.png b/images/icons/novalnet/novalnet_PayPal.png new file mode 100644 index 0000000000000000000000000000000000000000..9defac5ede192d140f03e63cbd985763d6003ec7 GIT binary patch literal 1976 zcmV;p2S@mcP)qMQ5T%;}lc^)cguEeBbl!?V%GFrDLggvHe^ZGjND(0?U#4M#^dNHp0nk*<^58kOarCAk^4PN zX^TVfudvOB>!IlE78IW^L-9F+W8s+sY(Fsp8xNSV{5||dbM_O;7>xS6*ic7_!0$ngg++xZ>}PSlAAY7UZHe^d7VxM}_^f3qJ{)79(< zUG1(2GSl?&1`qU;_#tz zkLOTx%sEPZiM+NnT?YA#(ziBSDeoKNCTiuS?yrEQ`Ep?U$xPuavwWJ4_u;z-aeiFg z+kv&aOdNriBt_~EeGA?L?zsxyVHxa=K+&0fod3p54?@MdJp<_Iw(Ep5@}#KvS$B|) zuw_aio)0CIoR|26b0eaL7)ff6LeAwj+ufjytFjlIR`%R$OsNZX%ye&_uQA(Po6WYo zo?Lh5*<^D@c0HC-E3Rj7zm2|rzW})jrY_Pk7=!tHGtKt=csg4s$nl*oqx+0NL5h3N zh&_()V#S9>5^08llU~YvyDassM_Vy4Q?TWz1Dg&uW^)JM4Br#4%UR_Jd==qxX zN6C_ekDO89ZsYz)bX3||p@B(;tTn8G`s ztG@lh`A-bQWwGX2Hc7YU{8v761RM5Or-ZVq@y8Eo^=s_DNzzYxR7S-qk4s^TUX=pZ zACfbxM)e>{Pgk*|<+S88KWg2Z`0A$5*OLr_D3f1_izG3L1Y0lw<;oq;XADpi?xm~E z@;lD$M7*L963)mQgY8G6>F80F%+H*EDWs{&`4F}q8%u(M+)pIGl$mYLOlOHT;m5XP zgIKqt)quT7oDE&{rXOV&C6r#!pphl`!tE!9sf}(l@B0NQ68VUDlX!v1 z=O?M|jrw+FM|LO|_r<%M-1|ucn0F#gX^X`7{|!YYt`(d=u9icwrSa4XB#@|*^s_S` zq|r{Q}mjJ^RI_F3g%kTg5IlYv;G-YLK^Z-8*5zak;NwD~fB z@RA*VjUe$ANgm)2?B)XxGg_VDc_YZU_!E$bSIyRb)@lty{A8UWVMRJ*Ofb#9GWc2KJbiNg` zpVcAng$kh2C(x&D*X8bgEfnmh%xXv8|BB}qNWKBj9#Q0fav>&ek~5VpzmRe^wOiv4 zTzBXOVakKDiD2Pdko8P3N-qMdchLDsbl&}tnvG`-2~$H1apOVKs1!RE#-y1c+`ms% z%_Yv)5oOx9p7X7`y1fGQjfa8cl5bMj*Ww!<-eNt3F@v*I`JQ3@*1)32f$XP&#T@%C z5a%;Q_K6=!telx&FYcN9pKAW+*S%(gd1mpBC0*vif)RC*nuWUlHK^GUYo#-*~uukF{KnzjI2- zyn6{VA8bgRt`W{Afs1km*X-2eHlwVgcy=E%`i;_<&g`XxALjfr_qQ^`wYj&Gzj2by zD+R*B9j-AJn`<4L#9H0>N1x}ROqk>6*m5`?cQIq)^Z+)ys^Zha(O98oN8D^7wK^fZ z#aclqiWzK4I8AApCUbgDG&9)1l$KQ~G$I4+%wZ(CS(WtbBp<~+T(^z;!>O+N40sgg z-iJGk$>4WbPvUl>6*e8H%C(8vY=}*VBCzVCP(CZ3uZLA1heBA@jzx%UUq+N7py1@} z0M-ogdqB~d{rqT0-<5E}G%Y*wcsJ8G86}@n0W#R6xXuH!D?bw&o+0LgNcJ1?38Es{ z(0sVrNEWPJWz2gKcQg7ZlmKRycMpjm$!i7xB&j@4P$8;gF=OT0GsH}QzTiZnq5Q%a z0e#8YE`cjP3dX<5Ld@}qYUXPi-D273h^C%ahS;&J>7n>{+n)f1E?@*Nc%};g0000< KMNUMnLSTaOw&x@O literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_cashpayment.png b/images/icons/novalnet/novalnet_cashpayment.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb4d4b2f03b009aaa48ef27f761f0d339341b0b GIT binary patch literal 2418 zcmZ`*X*ksD8~)8+vK&NXIA~~WVF)qS%D!a6WMu677RlJ1OgbnNoj4W7Q7MH;hU|EJxa|u{u`Eb9ets{+B}6Z&bZNACxF28`p#8p1X(Dsd&hr_dt4j6 zx<6+SzE?3RGB0C4v_Hi)9MD^gYZ>6y)2w6c6-*8}Q9>yB6twKlZ1Ty7W0h8ZA-e^8 zqwIyBL6$N00dHoNuanfe)lI>O^HPE|2&j#irp>I+r_qf?G=xoT*TTH_zxx<%-kF-3 z$}0C%yPqK~Fm<>_4-N9XfJpq;<+I_}kt6;#A1;Qz!YRq#z)=1IzMLeuq9uGoH7yZ> z35MMRP9XhlCqySDHTS@~)k2Zmiaf9qTwYyna=N2RaJH)UAOHUK&Bj9Ay#=Y^Sc6sA|UOEv>chF?n(#YrP%s6=?>JQvOcGjTE-JA0#E0IK~fiR`~ zst4E|v3;#W4@`uFifinIJrqD(z1^2fJbh{4X#?I$8+-GCH{(jNX0bh``)myDo* z9v+JoAp)V0^Y3dEzyaWtVBh;cwm5w{5 ztVM1lnBz9{8Y?cRySQw83HdoM%{d#Zgc=Sb9sHT#(&!7xYTmUmKZ3A?D$UW3_@n)F zDh6ZY&js!1R{r+!;gYl1K@RGtx*HuY@R5HXUUzgyiSr`W`gv1y2iZft=+#X4^NL8+^F`jOgL2W8zkF5sIg>$Iwwe~*fW^?;X_g-W`W=V7B_ zb;r4uqA&dP6J-*y)?$r>wmNrE1IaM|A4qA3lo;5N&m5*JL%b#QEZ--@R$j_ao5rm1 zpU9oAz7a*V7_BNJ>islummKSPR05H=TZfOmFw);-ufwX}9^=-=R)&Mqjz=BYQK1PSJ`v-Kpw@$vDMz6I;Y4oY%pF+wB= zU*@EocFEP%aipPl-q&cE)+gz6_USqluZ~`@#W)5B23iUT3B_Cr5#nxb36RNTKdnv7 zdXJvUC&K~>Iaa+lIk>Z`XrMBnfFs~oDvlMw(+S(Hdz$))T1|pY_4e)8n+pHP zXBq8UR)$T?)nNJEl9CL|%gd{)tE-~fap~zuAI1B9=Nl4mSL(Fk^k#3H3MbX>zqs(@ z*@3cJUhj6lCQ4MA`8*$abA^`MY~I9-7VdTkVP`ri|6TY1sqmL2hN{tbTLZQ@Df!gl z{pv*R0C0J0Wx%n-iS&v{l7hCy;tHgvn)k#uzS0Li78hgcmmb@6`_t752h;_w&)|Q9 z7A-`Mkz&1=Q;~i4ytW(K+CX}Xw5vfuL1c7fRr*)%q&kMFm_9^avbjW`Jz znV9eU(4kMm5;zj!jw`I5X^AJ-4YsT6N-@Xs+F>R_oULwRa>kccD()GKL0}kbxqN!r zGiNu0o(az*W+L1HR*-m-)m-`S9`}mZ!{*gIPqcK9z=?c2bf)@y-`7NXI7*j4(Zwge zu_Eq}2WT581o8cy{Gc-b5hBSO`Gyem^XX2lN@8-0e?j~w1tl3d@1|?Lm++yR5ZtXc^OBF`0Qwy+J-i4{Jg50s8buh}+MRr1 z{>X${>b{{RiP#a3Hm)=meE=ktUKI~?fHxPvK&3al$U_YYO;$*kYPzodNMECY52R%- zE<`I;l_e)cwQ3|Tij^PcEG(&Qjl6GYkYEu6_n!8_{C}WNDG}N?BZJDc- zIEHe>+w|T!u>%i;B8T@lROf=nuSKUhMc2zX+EJ`a;%SmqjFikgzRkJD0@%*f2*+I+GWdafX8%J=R`*^~#&kjv7bRoBVqSX?y5G;m&bHq1 zR1SOLQoO+Xf1HRiBS!gpMfu@;BK>#(Xks-^t75fOHBLKWHF2l3aGJV2io;@^P6_M( ek0C7FH^@Kk{~JzRE=l7V04uZerWI#Bum1WG zgtNdSvY3H^TNs2H8D`Cq01C2~c>21sKV+6+ur@!jW|uny1M@^r7sn8b({rbs&XaK! zY1O(D z9cFNDu}Cm<>X~q9#T z!g0^?6$8-f&+}#$v#6^yCN=7%WWE1*Z($y*P&wz$sPLpY%?5q~f^!7Sre~zES(V2sU*^z;ufMRrn-93ss&tW3(VHlU*?)sq$rk=ob*WcXwL%~ z*U~?qEGK#$oSC$~ft8u@XhB2Vz72wQx7O^m%&#c7TdIFS^UAr4EDuvw99Xtwj%6;p zne7>u%F1g&$x9?|&JC5Br*kuU_J=1grmV03Bl`X3THbm3Rz>IT*k|74Io7@I`S#7z z+S7Hdw{CdBR^&5hi*0+lZ1m->zgs!?%g-%d%V$$j=A+m8HS_3J&jYf$RZ>0g=g+&; z@#%Eo>5v{xFE7sJturOqUz^_RnZq5$wO@Ab#@knFioXlW%fI>f`LOdeXD0!sr2%ax z>Vl2S-99+!dI>65R@CfCQRY~3rcCup>Dh-bg+iCgDzQgj7cjnedv5VPKApCXJ3s%d ze*Qgf+wOhqJ{&rw!lQb=i_eiRyn`s?iB)cIfV^6`RH#cUnoVz_w&EnUL z8P`Ph*1iebHSf;XJ^RBhmdlzipEp+_hrJ{Ae4BWios(uou-Ca9KPGcCDW9qQ_wG4e zt;l{X)i)(UBH_ived>G@_esxSuPEHMRB-f5gF%R36Sad#=@&KdSls6U|6#nfvwTh8M{- z#=`%@XKvhm?}PYXH$!Gq{k%WG{Hj{w8c~vxSdwa$T$Bo=7>o=I&29nO2Eg!xGgdV9~(9;OXk;vd$@?2>{(D{(S%d literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_cc_maestro.png b/images/icons/novalnet/novalnet_cc_maestro.png new file mode 100644 index 0000000000000000000000000000000000000000..3e77c515f267e7d903d1f22ea84c85178002f0ca GIT binary patch literal 1050 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoN!3HEN%BSrGQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fID=-ieF_JSD}>!Q z9F>~2BgP|oKF8AeEl+05uxk%&u~9o}|3m2g?+sOqK4C4TEbAZ2=9G)K%-FT*@5X1# zg^y3)FL&QQL|e4vprp^E9BWIP?(*G&XZUR&JZC=MwYc}+!o$~}O}TWV_X+2m1MAFA zhV5z1otwAB^Wx4^pP#XpD@(=iS-Pnt+jqt8#~giIJ^P+D@6&ej`D?x7^i$dPmKkZy zKEc1mv$*c=ZWJ%9pPjNmxih2eh2!bk!%aGwJO{T;-F47yv$!WK`{X|tM7R1zAKhT~ zqN7Or>V2PT&uyH^o&Om*SM6WLTU?!}qVjHKtZCWbH4;XpvppaEIk6y2sA^(Oqc-QW z4{~YNS+mS+qy8Stc$?2s&zB!2d+Uz(s`w9y_*rmks|?M89%(9CDzvCCUAuA5 z2`#_mTWqW2U+>IsU~5uvyJWInkLA*h?MwBiG%bD6?d*z!cy6a}P9-W=dpWeJq^~>|B z`02U(Hl5j|z9IVAt;dx)q0g#wo7^}aJ_M>c_C4oD&+CBm^W%*FFWbmIJ;lGqecp~n z%{8a$8l@}S`=@j*y)Sob_xd|Irmx>F`OmojDf`h&pI+S(M3Kt8y|^83O~erl*Tzh{fsNspqp}LPd_-Kfh<5pZ3Wo&1dnl$%Y*# z4_#@npP*yH{rbIL)0ChVz1R*$aitetpZGbNq<3G`d+ns-6t2~@jmwowtK;sLt(QzP zy)Uats(ntoxBL5!8QP^u>1yef@4w%9-(P%xx6_JlpG%HsCCcs{5^UCCn(VNu;Narr z#$RTidYyJz_S4m-so}jRCLNgLYnqbD{w zPGeohxNv)v+`fMP@_jwiA1!9m=bBQU7&3ML-d7*XmK|R^)$QwA)0C-FU42Jq^z-cD zbosKu!dwfAEU)X3kW{rKhf* zc`2AYF`1c@p*r3##=m-L-V%>l|LcqXUsbco>6I~NI&Zur$MksLkKM)s6Sld}`ne&@ z#UexE5z_$`zBlVMS1aY3PhnXxd+&l@)86r>HGEA}*q?mh{W(UBcb<=T1zH&MJT>F~ zA$!|6rB~NZlgE7Z978_amCko|xVfaSy&^nWUVq`zjD(a`YpmC+pY^?C$*<0)wq`<{ zN5Sp8`Jtx;e}-J*t!8Ks_q%hW==mEi(b5mI9bYkh{<8C@-PRw=RA-&rYi*#mFG$Aa z!QM}<(_Wv-xcTOWxJp{ril-0Q8P!iDGo7@R+FY}`;M!Ri`O}k^3N~sUxOe!A@B5!B z#k-Ptx7Y8yvTyY-uHS_#bd%>9Y*0C2e1PQwqn_rkSho9qGG@|mum7>jt~lDUr^kT# z$N}9@+xJs1ukHIMCwXVzQ@h32F16oDn3MbL4cp~Tqv)FERjgI(CcP@&a<}P6e0ulG z>z6xs8>Rp47Y(`pS3Ieq@PNmRgEawf8&@CjU|7S*&nWppr=Tm(C%Z&`i|+%*2U2&< zUz8PG<@(LuaK7c;`@gxn_ygE_7`GqV#o7Lk=M2O3M%M>P9UCP%vKzSB(-+=n`p!Jx z?chnR3mgaBno=I&2mdKI;Vst0CYmn82|tP literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_cc_visa.png b/images/icons/novalnet/novalnet_cc_visa.png new file mode 100644 index 0000000000000000000000000000000000000000..6b94ca81165c3e32a931acc22aa4f3c9f20a16ff GIT binary patch literal 2908 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 literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_eps.png b/images/icons/novalnet/novalnet_eps.png new file mode 100644 index 0000000000000000000000000000000000000000..02875aeefb8558e1cf37ef1a49ce28ef8042c188 GIT binary patch literal 1064 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 Ud2z{QJOBUy07*qoM6N<$f@F@DT>t<8 literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_postfinance_card.png b/images/icons/novalnet/novalnet_postfinance_card.png new file mode 100644 index 0000000000000000000000000000000000000000..e704b07653c2cb1fb9b233f718e1c7b5383aeb5c GIT binary patch literal 2351 zcmV+~3DEY5P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmYxQqY*xQqeJ_PZ|t000McNliru;t3N9F)2}; zkRbp72l+`vK~z}7t(Z%U99I>FzjN=cS3jqF9-i^Uj_te@ti+KLL?UDq0Wu_uC`wo% z0YZp9Y}m15#ezi^>Z3#93moc0Ozt-n%Ncg4+l9tH2L| z1o#{gc11+2AmI&=LogY3au`9ZfP&_JC%U-QBwzX+61=q6-46IE@a#lb1!H!OC*qjl zwb3W{;5~%F&Tm9w#Ka&6JU}D#KiXjP^-qw%(s=wBwi=Ghwt(-xwimPos^dTxKJq;O z`vFH54BvY?z*->+hhSL_?=R()6XEPTIj_H!bMG-jqb@x0ctD;*;GjP!6UPxoAx(3f zGgvG1dKqEp=npdDBw*v8m(et*^VW50421-pc9q;k7q1wpz-{ znsV|U!|J+HDG6uK=gc&POIJK6@3jn4xbU&(=fCQa2>gEa;S7W|@W{Mww{~><;n}0D# zJ&!(e6!+#QY;L94!7>jVJ3(V=iX->j!MCDESX%m+b00SO@?%fZ+Pum$&z!-=E3E$I zBHj1bD4(3Abl(i>CzEJm8AbJofIk6ez~g3qMppVRaTH*TrPFQG?Q|(uDzvs*)azCH z{XX6cVdx0Mm|m|lR3r$t)1A86y@k1`#1mQ@r;Cfn#f{O_dK=`@;*g-dtw> z2d7BxYM|Lz1wsFg=1=YqEx{QyL);;}RPo+`=EIy2LGV~JKvj`ZqNt){N+^n$3gS*6 z?hs-RgGt89*tmLvPdf~j*FYect&CYiC!qJShXMg&9II;~S6523+d1tGgJw{vIp!B4 zn$y>)#2@b}ofKbq zwRrb4QaBs)u-}vV;5sb+jMO6EE9WH8qTCvuX^?Qh^g2afO1`<>pVibcS`);wch^5Rl6Pi;|QEgmK5!)cmTDYK#k(j%V&r+#G zdu-me`wB!n){g2ne6B)6X7gSL~ zjJU$WIfCx9;Vjw!2@$c|g6%hM>**u&2Cs@O_JP*L7}umf2yv#1H}j}ZabXkhJt{La z8Wu54tgE0nyw6b0=yrP;V-RD=Qok*zh{KqGELT)hP_S08*5JJohW67yk9-E_KY)!b zLz2V{vY3V0h(;}CqXnDoI$P~^>a`gvr4Ie9!rJ;xkTNbJhbS z#PanPc|NpUwGxrU0c-0W>eZNDKVvY+sMTV+-IP-&=O>h(fEH6n@wu2<2MmH?@vzYB zWrRTwpZ5sEh*D({Pm5Yr>E}lgZBecsB~5!wH5#A>l@g^SK{1reAyT|MqiDEAUtEaD zvK&<<2rO~rs8&KsNr3lCub&Y(OPb~5z#Y(R0@{?HCfj%}ljz~+@atW4kj&QmN__xQ zH6}cTiu1mIp14^zCOoN{zKsMYMg6*pT@Vog(`3780)%8&+Ks1~7LT=7jdpTr?0DF! zG5~&yDR*|I=gpUZ99#n{77^>fB)Hm7#8#fBxAd&4UL{(5Uh>Vqq1iQT{VDRzzhbM8 zq3I>W#>H$FzKH*NMr+eN1Nc7`CwMN?hVUr>001R)MObuXVRU6WV{&C-bY%cCFflkS zFgYzTIaDz)Iy5;tG%+nOG&(Ra?P2M)0000bbVXQnWMOn=I&E)cX=Zr<{98FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08f VWO;GPWjp`?002ovPDHLkV1kZEEbjmS literal 0 HcmV?d00001 diff --git a/images/icons/novalnet/novalnet_prepayment.png b/images/icons/novalnet/novalnet_prepayment.png new file mode 100644 index 0000000000000000000000000000000000000000..91042816085bcabe2412d107656e19acc7cf54d5 GIT binary patch literal 978 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 MODULE_PAYMENT_NOVALNET_VENDOR_ID, + 'product' => MODULE_PAYMENT_NOVALNET_PRODUCT_ID, + 'tariff' => $tariff, + 'auth_code' => MODULE_PAYMENT_NOVALNET_AUTH_CODE, + 'test_mode' => ($testMode == 'True') ? 1 : 0, + ); + + } + + /** + * Get customer details + * + * @return array + */ + public static function getCustomerfields() + { + global $db; + + $customerId = (isset($_SESSION['customer_id'])) ? $_SESSION['customer_id'] : ''; + if (!empty($customerId)) { + $customer = $db->Execute("SELECT customers_gender, customers_dob, customers_fax FROM " . TABLE_CUSTOMERS . " WHERE customers_id='" . (int) $customerId . "'"); + + if ($customer->RecordCount() > 0) { + $customer = $customer->fields; + } + return $customer; + } + } + + /** + * Form Customer details + * + * @param $request array + * @param $data array + * + * @return none + */ + public static function getCustomerDetails(&$request, $data) + { + $customer = self::getCustomerfields(); + + $nn_customer_id = (isset($_SESSION['customer_id'])) ? $_SESSION['customer_id'] : ''; + $customer_birthdate = ($customer['customers_dob'] != '0001-01-01 00:00:00') ? date('Y-m-d', strtotime($customer['customers_dob'])) : ''; + $request['first_name'] = !empty($data['billing']['firstname']) ? $data['billing']['firstname'] : $data['customer']['firstname']; + $request['last_name'] = !empty($data['billing']['lastname']) ? $data['billing']['lastname'] : $data['customer']['lastname']; + $request['street'] = !empty($data['billing']['street_address']) ? $data['billing']['street_address'] : $data['customer']['street_address']; + $request['search_in_street'] = 1; + $request['city'] = !empty($data['billing']['city']) ? $data['billing']['city'] : $data['customer']['city']; + $request['zip'] = !empty($data['billing']['postcode']) ? $data['billing']['postcode'] : $data['customer']['postcode']; + $request['email'] = !empty($data['billing']['email_address']) ? $data['billing']['email_address'] : $data['customer']['email_address']; + $request['country_code'] = !empty($data['billing']['country']['iso_code_2']) ? $data['billing']['country']['iso_code_2'] : $data['customer']['country']['iso_code_2']; + $request['customer_no'] = !empty($nn_customer_id) ? $nn_customer_id : 'guest'; + $request['tel'] = !empty($data['billing']['telephone']) ? $data['billing']['telephone'] : $data['customer']['telephone']; $request['lang'] = ((isset($_SESSION['language']) && $_SESSION['language'] == 'english') ? 'EN' : 'DE'); + $company = !empty($data['billing']['company']) ? $data['billing']['company'] : $data['customer']['company']; + + if (!empty($company)) + $request['company'] = !empty($data['billing']['company']) ? $data['billing']['company'] : $data['customer']['company']; + + if (!empty($customer['customers_gender'])) + $request['gender'] = $customer['customers_gender']; + + if (!empty($customer_birthdate)) + $request['birth_date'] = $customer_birthdate; + + if (!empty($customer['customers_fax'])) + $request['fax'] = $customer['customers_fax']; + + } + + /** + * Get Order details + * + * @param $request array + * @param $data array + * + * @return none + */ + public static function getOrderDetails(&$request, $data) + { + $request['amount'] = $data['order_amount']; + $request['currency'] = $data['info']['currency']; + } + + /** + * Get Payment details + * + * @param $request array + * @param $data array + * @param $payment string + * + * @return none + */ + public static function getPaymentDetails(&$request, $data, $payment) + { + $redirectPayments = array('novalnet_cc','novalnet_ideal', 'novalnet_PayPal', 'novalnet_banktransfer', 'novalnet_eps', 'novalnet_giropay', 'novalnet_przelewy24', 'novalnet_postfinance', 'novalnet_postfinance_card'); + + $request['payment_type'] = self::getPaymentTypeKey($payment,'type'); + $request['key'] = self::getPaymentTypeKey($payment,'key'); + + if (in_array($payment, array('novalnet_invoice', 'novalnet_cc', 'novalnet_sepa', 'novalnet_PayPal', 'novalnet_instalment_sepa', 'novalnet_instalment_invoice', 'novalnet_guarantee_invoice', 'novalnet_guarantee_sepa'))) { + $paymentName = strtoupper($payment); + $onholdLimit = constant('MODULE_PAYMENT_'.$paymentName.'_ONHOLD_LIMIT'); + // To process on hold product + if ((constant('MODULE_PAYMENT_'.$paymentName.'_ONHOLD') == 'Authorize') && (!empty($onholdLimit) && ($request['amount'] >= trim($onholdLimit)) || empty($onholdLimit))) { + $request['on_hold'] = 1; + } + } + + if ($payment == 'novalnet_invoice') { + $dueDate = MODULE_PAYMENT_NOVALNET_INVOICE_DUE_DATE; + $dueDate = trim($dueDate); + if ($dueDate != '') { + $request['due_date'] = date('Y-m-d', strtotime('+' .$dueDate . ' days')); + } + } + + if (in_array($payment, array('novalnet_sepa', 'novalnet_guarantee_sepa'))) { + $sepaDueDate = self::sepaDuedate($paymentName); + + if( !empty($sepaDueDate) ) { + $request['sepa_due_date'] = date('Y-m-d', strtotime('+'.$sepaDueDate.' days')); + } + } + + if (in_array($payment, array('novalnet_sepa', 'novalnet_guarantee_sepa', 'novalnet_instalment_sepa'))) { + $request['bank_account_holder'] = strip_tags($data[$payment.'_bank_account_holder']); + $request['iban'] = $data[$payment.'_bank_iban']; + } + + if (in_array($payment, array('novalnet_guarantee_invoice', 'novalnet_guarantee_sepa', 'novalnet_instalment_invoice', 'novalnet_instalment_sepa'))) { + if (isset($data[$payment.'_birthdate']) && !empty($data[$payment.'_birthdate'])) { + $request['birth_date'] = date('Y-m-d', strtotime($data[$payment.'_birthdate'])); + } + if (in_array($payment, array('novalnet_instalment_invoice', 'novalnet_instalment_sepa'))) { + $period = constant('MODULE_PAYMENT_'.$paymentName.'_PERIOD'); + $request['instalment_cycles'] = $data[$payment.'_period']; + $request['instalment_period'] = strtolower($period); + } + } + + if ($payment == 'novalnet_invoice') { + $request['invoice_type'] = 'INVOICE'; + } elseif ($payment == 'novalnet_prepayment') { + $request['invoice_type'] = 'PREPAYMENT'; + } elseif ($payment == 'novalnet_cashpayment') { + $dueDate = trim(MODULE_PAYMENT_NOVALNET_CASHPAYMENT_SLIP_EXPIRY_DATE); + $barzahlenDueDate = ($dueDate) ? (date('Y-m-d', strtotime('+' . $dueDate . ' days'))) : ''; + if ($barzahlenDueDate != '') { + $request['cp_due_date'] = $barzahlenDueDate; + } + } elseif ($payment == 'novalnet_cc') { + $request['unique_id'] = $data['nn_cc_uniqueid']; + $request['pan_hash'] = $data['nn_cc_pan_hash']; + $request['nn_it'] = 'iframe'; + $request['cc_3d'] = 1; + } + if (in_array($payment, $redirectPayments)) { + self::getRedirectParams($request, $payment); + } + } + + /** + * Get SEPA due date + * + * @param $paymentName string + * + * @return string + */ + public static function sepaDuedate($paymentName) + { + $sepaDueDate = constant('MODULE_PAYMENT_'.$paymentName. '_PAYMENT_DUE_DATE'); + $sepaDueDate = trim($sepaDueDate); + + if ($sepaDueDate != '' && $sepaDueDate <= 14 && $sepaDueDate >= 2) { + return $sepaDueDate; + } + } + + /** + * Get payment key & payment type + * + * @param $paymentName string + * @param $field string + * + * @return string + */ + public static function getPaymentTypeKey($paymentName, $field) + { + $payment = array( + 'novalnet_sepa' => array('key' =>37, 'type' => "DIRECT_DEBIT_SEPA"), + 'novalnet_cc' => array('key' => 6, 'type' => "CREDITCARD"), + 'novalnet_invoice' => array('key' => 27, 'type' => "INVOICE"), + 'novalnet_prepayment' => array('key' => 27, 'type' => "PREPAYMENT"), + 'novalnet_guarantee_invoice' => array('key' => 41, 'type' => "GUARANTEED_INVOICE"), + 'novalnet_guarantee_sepa' => array('key' => 40, 'type' => "GUARANTEED_DIRECT_DEBIT_SEPA"), + 'novalnet_ideal' => array('key' => 49, 'type' => "IDEAL"), + 'novalnet_banktransfer' => array('key' => 33, 'type' => "ONLINE_TRANSFER"), + 'novalnet_giropay' => array('key' => 69, 'type' => "GIROPAY"), + 'novalnet_cashpayment' => array('key' => 59, 'type' => "CASHPAYMENT"), + 'novalnet_przelewy24' => array('key' => 78, 'type' => "PRZELEWY24"), + 'novalnet_eps' => array('key' => 50, 'type' => "EPS"), + 'novalnet_instalment_invoice' => array('key' => 96, 'type' => "INSTALMENT_INVOICE"), + 'novalnet_instalment_sepa' => array('key' => 97, 'type' => "INSTALMENT_DIRECT_DEBIT_SEPA"), + 'novalnet_PayPal' => array('key' => 34, 'type' => "PAYPAL"), + 'novalnet_postfinance_card' => array('key' => 87, 'type' => "POSTFINANCE_CARD"), + 'novalnet_postfinance' => array('key' => 88, 'type' => "POSTFINANCE"), + ); + return $payment[$paymentName][$field]; + } + + /** + * Get system details + * + * @param $request array + * @param $data array + * + * @return none + */ + public static function getSystemDetails(&$request, $data) + { + $remoteIp = zen_get_ip_address(); + $systemIp = $_SERVER['SERVER_ADDR']; + $request['system_name'] = 'Zencart'; + $request['system_version'] = PROJECT_VERSION_MAJOR.'.'.PROJECT_VERSION_MINOR . '-NN-2.0.0'; + $request['remote_ip'] = (filter_var($remoteIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || empty($remoteIp)) ? '127.0.0.1' : $remoteIp; + $request['system_ip'] = (filter_var($systemIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || empty($systemIp)) ? '127.0.0.1' : $systemIp; + $request['system_url'] = ((ENABLE_SSL == true) ? HTTPS_SERVER : HTTP_SERVER); + $notifyUrl = trim(MODULE_PAYMENT_NOVALNET_CALLBACK_NOTIFY_URL); + if (!empty($notifyUrl)) + $request['notify_url'] = $notifyUrl; + } + + /** + * Return payment amount of given order + * + * @param $data array + * @param $payment string + * + * @return integer + */ + public static function getPaymentAmount($data, $payment) + { + global $currencies, $messageStack; + + $total = ((isset($_SESSION['customers_status']) && $_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1)) ? ($data['info']['total'] + $data['info']['tax']) : $data['info']['total']; + + $totalAmount = number_format($total * $currencies->get_value($data['info']['currency']), 2); + $amount = str_replace(',', '', $totalAmount); + $amount = intval(round($amount * 100)); + + if (preg_match('/[^\d\.]/', $amount)) { + $messageStack->add_session('checkout_payment', MODULE_PAYMENT_NOVALNET_AMOUNT_ERROR_MESSAGE . '', 'error'); + zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false)); + } + + return $amount; + } + + /** + * Get Redirect request + * + * @param $request array + * @param $payment string + * + * @return none + */ + public static function getRedirectParams(&$request, $payment) + { + $request['return_method'] = $request['error_return_method'] = 'POST'; + $request['return_url'] = $request['error_return_url'] = zen_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL'); + $request['user_variable_0'] = ((ENABLE_SSL == true) ? HTTPS_SERVER:HTTP_SERVER); + $request['implementation'] = 'ENC'; + $request['input3'] = 'cart_id'; + $request['inputval3'] = $_SESSION['cartID']; + $request['uniqid'] = self::getUniqueid(); + } + + /** + * Generate encode data + * + * @param $request array + * + * @return none + */ + public static function generateEncodeValue(&$request) + { + foreach (array('auth_code', 'product', 'tariff', 'amount', 'test_mode') as $key) { + if (isset($request[$key])) { + // Encoding process + $request[$key] = htmlentities(base64_encode(openssl_encrypt($request[$key], "aes-256-cbc", MODULE_PAYMENT_NOVALNET_PAYMENT_ACCESS_KEY, true, $request['uniqid']))); + } + } + + // Generate hash value + $request['hash'] = self::generateHashValue($request); + } + + /** + * Generate decode data + * @param $data + * + * @return none + */ + public static function decodePaygateResponse(&$data) + { + foreach (array('auth_code','product','tariff','amount','test_mode') as $key) { + if (isset($data[$key])) { + // Decoding process + $data[$key] = openssl_decrypt(base64_decode($data[$key]), "aes-256-cbc", MODULE_PAYMENT_NOVALNET_PAYMENT_ACCESS_KEY, true, $data['uniqid']); + } + } + + return $data; + } + + /** + * Perform HASH Validation with paygate response + * + * @param $data array + * + * @return boolean + */ + public static function validateHashResponse($data) + { + // Check for hash error + return ($data['hash2'] != self::generateHashValue($data)); + } + + /** + * Get hash value + * + * @param $request array + * + * @return mixed + */ + public static function generateHashValue($request) + { + // Hash generation using sha256 and encoded merchant details + return hash('sha256', ($request['auth_code'].$request['product'].$request['tariff'].$request['amount'].$request['test_mode'].$request['uniqid'].strrev(MODULE_PAYMENT_NOVALNET_PAYMENT_ACCESS_KEY))); + + } + + /** + * Gets the Unique Id + * + * @return string + */ + public static function getUniqueid() + { + $randomArray = array('8','7','6','5','4','3','2','1','9','0','9','7','6','1','2','3','4','5','6','7','8','9','0'); + shuffle($randomArray); + return substr(implode($randomArray, ''), 0, 16); + } + + /** + * Function to communicate transaction parameters with Novalnet Paygate + * + * @param $paygateUrl string + * @param $data array + * @param $payment string + * + * @return array + */ + public static function doPaymentCurlCall($paygateUrl, $data, $payment = '') + { + // Initiate cURL. + $curlProcess = curl_init($paygateUrl); + // Set cURL options. + curl_setopt($curlProcess, CURLOPT_POST, 1); + curl_setopt($curlProcess, CURLOPT_POSTFIELDS, http_build_query($data)); + curl_setopt($curlProcess, CURLOPT_FOLLOWLOCATION, 0); + curl_setopt($curlProcess, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curlProcess, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curlProcess, CURLOPT_RETURNTRANSFER, 1); + + // Custom CURL time-out. + curl_setopt($curlProcess, CURLOPT_TIMEOUT, 240); + + // Execute cURL. + $response = curl_exec($curlProcess); + + // Handle cURL error. + if (curl_errno($curlProcess)) { + $messageStack->add_session('checkout_payment', utf8_decode('error_message=' .curl_error($curlProcess)) . '', 'error'); + zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false)); + } + + // Close cURL. + curl_close($curlProcess); + + return $response; + } + + /** + * Check order status + * + * @param $orderStatus integer + * + * @return integer + */ + public static function checkDefaultOrderStatus($orderStatus) + { + return !empty($orderStatus) ? $orderStatus : DEFAULT_ORDERS_STATUS_ID; + } + + /** + * Form transaction comments + * + * @param $tid integer + * @param $testMode integer + * + * @return string + */ + public static function formPaymentComments($tid, $testMode) + { + $transactionComments = ''; + if ($tid) { + $transactionComments .= PHP_EOL.MODULE_PAYMENT_NOVALNET_TRANSACTION_DETAILS.PHP_EOL.MODULE_PAYMENT_NOVALNET_TRANSACTION_ID . $tid; + } + + // Add test_mode text + if ($testMode) { + $transactionComments .= PHP_EOL.MODULE_PAYMENT_NOVALNET_TEST_ORDER_MESSAGE.PHP_EOL; + } + + return $transactionComments; + } + + /** + * Return Invoice / Prepayment comments + * + * @param $data array + * @param $amount integer + * + * @return string + */ + public static function formInvoicePrepaymentComments($data, $amount = '') + { + $amount = !empty($amount) ? $amount : number_format($data['amount'], 2, ',', ''); + + $transComments = PHP_EOL. MODULE_PAYMENT_NOVALNET_INVOICE_COMMENTS_PARAGRAPH.PHP_EOL; + $dueDate = $data['due_date']; + $transComments .= ($dueDate != '') ? MODULE_PAYMENT_NOVALNET_DUE_DATE.': '.date(DATE_FORMAT, strtotime($dueDate)).PHP_EOL : ''; + $transComments .= MODULE_PAYMENT_NOVALNET_ACCOUNT_HOLDER.': '.$data['invoice_account_holder']. PHP_EOL; + $transComments .= MODULE_PAYMENT_NOVALNET_IBAN.': '.$data['invoice_iban']. PHP_EOL; + $transComments .= MODULE_PAYMENT_NOVALNET_SWIFT_BIC.': '.$data['invoice_bic'].PHP_EOL; + $transComments .= MODULE_PAYMENT_NOVALNET_BANK.': '.$data['invoice_bankname'].' '.$data['invoice_bankplace'].PHP_EOL; + $transComments .= MODULE_PAYMENT_NOVALNET_AMOUNT.': '. $amount. ' ' . $data['currency'].PHP_EOL; + return $transComments; + } + + /** + * Check transaction status message + * + * @param $response array + * + * @return string + */ + public static function getTransactionMessage($response) + { + return (!empty($response['status_message']) ? $response['status_message'] : !empty($response['status_desc']) ? $response['status_desc'] : (!empty($response['status_text']) ? $response['status_text'] : '')); + } + + /** + * Return Invoice / Prepayment payment reference comments + * + * @param $orderId integer + * @param $data array + * @param $payment string + * + * @return string + */ + public static function novalnetReferenceComments($orderId, $data, $payment) + { + $comments = MODULE_PAYMENT_NOVALNET_PAYMENT_MULTI_TEXT . PHP_EOL; + $comments .= MODULE_PAYMENT_NOVALNET_INVPRE_REF1. ': TID'.' '. $data['tid'] . PHP_EOL; + if ($payment != 'novalnet_instalment_invoice') { + $comments .= MODULE_PAYMENT_NOVALNET_INVPRE_REF2 .': BNR-' . (!empty($data['product']) ? $data['product'] : MODULE_PAYMENT_NOVALNET_PRODUCT_ID) . '-' . $orderId. PHP_EOL; + } + + + return $comments; + } + + /** + * Build the postback call for updating order_no + * + * @param $data array + * + * @return none + */ + public static function postBackCall($data) + { + $payment = $data['payment']; + // Second call for updating order_no + $urlparam = array( + 'vendor' => $_SESSION['novalnet'][$payment]['vendor'], + 'product' => $_SESSION['novalnet'][$payment]['product'], + 'tariff' => $_SESSION['novalnet'][$payment]['tariff'], + 'auth_code' => $_SESSION['novalnet'][$payment]['auth_code'], + 'key' => $_SESSION['novalnet'][$payment]['payment_id'], + 'status' => 100, + 'tid' => $_SESSION['novalnet'][$payment]['tid'], + 'order_no' => $data['order_no'], + ); + + // Add invoice_ref parameter for Invoice and Prepayment + if (in_array($_SESSION['novalnet'][$payment], array('novalnet_invoice', 'novalnet_guarantee_invoice'))) { + $urlparam['invoice_ref'] .= 'BNR-'.$_SESSION['novalnet'][$payment]['product'].'-'.$data['order_no']; + } + + // Send parameters to Novalnet paygate + self::doPaymentCurlCall('https://payport.novalnet.de/paygate.jsp', $urlparam, $payment); + + // Unset all Novalnet session value + if (isset($_SESSION['novalnet'])) { + unset($_SESSION['novalnet']); + } + } + + /** + * Merchant details + * + * @param $inputParams array + * + * @return array + */ + public static function paymentInitialParams($inputParams) + { + return array( + 'vendor' => $inputParams['vendor'], + 'product' => $inputParams['product'], + 'tariff' => $inputParams['tariff'], + 'auth_code' => $inputParams['auth_code'], + 'payment_id' => !empty($inputParams['key']) ? $inputParams['key'] : $inputParams['payment_id'], + ); + } + + /** + * Built Cashpayment comments + * + * @param $response array + * + * @return string + */ + public static function formCashpaymentComments($response) + { + global $db; + $barzahlenComments = ''; + + $slipDueDate = !empty($response['cp_due_date']) ? $response['cp_due_date']: $response['due_date']; + + $barzahlenComments .= MODULE_PAYMENT_NOVALNET_CASHPAYMENT_SLIP_EXPIRY_DATE_TEXT . ': '.date('d.m.Y', strtotime($slipDueDate)).PHP_EOL; + + $nearestStore = self::getNearestStore($response); + $nearestStore['nearest_store'] = $nearestStore; + if (!empty($nearestStore)) { + $barzahlenComments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_CASHPAYMENT_NEAREST_STORE_DETAILS_TEXT.PHP_EOL; + } + + $nearestStore['cp_due_date'] = $slipDueDate; + $i =0; + foreach ($nearestStore as $key => $values) { + $i++; + if (!empty($nearestStore['nearest_store_title_'.$i])) { + $barzahlenComments .= PHP_EOL . $nearestStore['nearest_store_title_'.$i]; + } + if (!empty($nearestStore['nearest_store_street_'.$i])) { + $barzahlenComments .= PHP_EOL . $nearestStore['nearest_store_street_'.$i]; + } + if (!empty($nearestStore['nearest_store_city_'.$i])) { + $barzahlenComments .= PHP_EOL . $nearestStore['nearest_store_city_'.$i]; + } + if (!empty($nearestStore['nearest_store_zipcode_'.$i])) { + $barzahlenComments .= PHP_EOL . $nearestStore['nearest_store_zipcode_'.$i]; + } + + if (!empty($nearestStore['nearest_store_country_'.$i])) { + $result = $db->Execute("select countries_name from countries where countries_iso_code_2='". $nearestStore['nearest_store_country_'.$i] ."'"); + $barzahlenComments .= PHP_EOL . $result->fields['countries_name'].PHP_EOL; + } + } + + return $barzahlenComments; + } + + /** + * Get nearest store details + * @param $response + * + * @return array + */ + public static function getNearestStore($response) + { + $stores = array(); + foreach ($response as $sKey => $values) { + if (stripos($sKey, 'nearest_store')!==false) { + $stores[$sKey] = $values; + } + } + return $stores; + } + + /** + * Get Instalment Cycles from Instalment payment settings. + * + * @param $payment string + * @param $order object + * + * @return array + */ + public static function getInstalmentCycles($payment, $order) + { + $paymentName = strtoupper($payment); + + $paymentCycle = constant('MODULE_PAYMENT_' . $paymentName . '_PERIOD'); + $totalPeriod = constant('MODULE_PAYMENT_' . $paymentName . '_CYCLE'); + + if (!empty($totalPeriod)) { + $totalPeriod = explode(',',$totalPeriod); + + $i = 0; + $cycles = array(array('id'=> $i,'text'=>'Select')); + if ( 1 == $paymentCycle ) { + $paymentCycle = ''; + } + sort($totalPeriod); + + $clength=count($totalPeriod); + for($x=0;$x<$clength;$x++){ + $totalPeriod[$x]; + } + + $totalPeriod = array_unique($totalPeriod); + + foreach ( $totalPeriod as $period ) { + $amount = self::getPaymentAmount((array)$order, $payment); + $cycle = ($amount / $period); + if ( $cycle >= 999 ) { + $cycles[] = array('id' => $period,'text' => sprintf(MODULE_PAYMENT_NOVALNET_CYCLES, $period ) . ' / ' . sprintf( '%0.2f', $cycle/100 ).' ' . $order->info['currency'] . sprintf(MODULE_PAYMENT_NOVALNET_PER_MONTH, $paymentCycle )); + $i++; + } + } + } + + if ( $i == 0 ) { + return $i; + } else { + return $cycles; + } + } + + /** + * Get Instalment PlanF Details. + * + * @param $payment string + * + * @return array + */ + public static function getInstalmentPlanDetails($payment) + { + $paymentName = strtoupper($payment); + $cyclePeriod = constant('MODULE_PAYMENT_' . $paymentName . '_PERIOD'); + $totalPeriod = constant('MODULE_PAYMENT_' . $paymentName . '_CYCLE'); + $totalPeriod = explode(',',$totalPeriod); + sort($totalPeriod); + + $clength=count($totalPeriod); + for($x=0;$x<$clength;$x++){ + $totalPeriod[$x]; + } + + $totalInstalmentCycle = !empty( $totalPeriod ) ? $totalPeriod[count($totalPeriod)-1]:''; + $currentMonthInvoice = date('m'); + + for ( $i=0; $i<$totalInstalmentCycle; $i++ ) { + $lastDay = date('Y-m-d', strtotime( '+'.$cyclePeriod * $i.'months' ) ); + $instlmentDateMonth[] = date('m', strtotime( '+'.$cyclePeriod * $i.'months' ) ); + if( $currentMonthInvoice > 12 ) { + $currentMonthInvoice = $currentMonthInvoice - 12; + } + if ( $currentMonthInvoice == $instlmentDateMonth[$i] ) { + $instlmentDateInvoice[] = date('Y-m-d', strtotime( '+'.$cyclePeriod * $i.'months' ) ); + } else { + $instlmentDateInvoice[] = date('Y-m-d', strtotime( $instlmentDateInvoice[$i].' last day of previous month' , strtotime ( $lastDay ) ) ); + } + $currentMonthInvoice = $currentMonthInvoice + $cyclePeriod; + } + + return $currentMonthInvoice; + } + + /** + * Form guarantee field + * + * @param $name string + * @param $customerDetails array + * + * @return string + */ + public static function getGuaranteeField($name, $customerDetails) + { + $birthDate = (isset($customerDetails['customers_dob']) && $customerDetails['customers_dob'] != '0001-01-01 00:00:00') ? date('Y-m-d', strtotime($customerDetails['customers_dob'])) : ''; + + return zen_draw_input_field($name, $birthDate, 'id="'.$name.'" placeholder="'.MODULE_PAYMENT_NOVALNET_GUARANTEE_DOB_FORMAT.'" autocomplete="OFF" maxlength="10" ') . '
'; + } + + /** + * Check guarantee payment condition + * + * @param $order array + * @param $payment string + * + * @return string + */ + public static function checkGuaranteeConditions($order, $payment) + { + // Get payment name in caps + $paymentName = strtoupper($payment); + + $min_amount = (in_array($payment, array('novalnet_instalment_invoice', 'novalnet_instalment_sepa'))) ? '1998' : '999'; + + // Get guarantee minimum and maximum amount value + $minimumAmount = trim(constant('MODULE_PAYMENT_'.$paymentName.'_MIN_AMOUNT_LIMIT')) ? trim(constant('MODULE_PAYMENT_'.$paymentName.'_MIN_AMOUNT_LIMIT')) : $min_amount; + + // Get order details + $customerIsoCode = strtoupper($order['customer']['country']['iso_code_2']); + $amount = self::getPaymentAmount((array)$order, $payment); + + // Delivery address + $deliveryAddress = array( + 'street_address' => $order['delivery']['street_address'], + 'city' => $order['delivery']['city'], + 'postcode' => $order['delivery']['postcode'], + 'country' => $order['delivery']['country']['iso_code_2'], + ); + + // Billing address + $billingAddress = array( + 'street_address' => $order['billing']['street_address'], + 'city' => $order['billing']['city'], + 'postcode' => $order['billing']['postcode'], + 'country' => $order['billing']['country']['iso_code_2'], + ); + + if ((((int) $amount >= (int) $minimumAmount) && in_array($customerIsoCode, array('DE', 'AT', 'CH')) && $order['info']['currency'] == 'EUR' && $deliveryAddress === $billingAddress)) { + return array('guarantee', ''); + } else { + $guaranteeError = ''; + if (!in_array($customerIsoCode, array('DE', 'AT', 'CH'))) { + $guaranteeError .= MODULE_PAYMENT_NOVALNET_FORCE_GUARANTEE_ERROR_MESSAGE_COUNTRY; + } + if ($order['info']['currency'] !== 'EUR' ) { + $guaranteeError .= '
'.MODULE_PAYMENT_NOVALNET_FORCE_GUARANTEE_ERROR_MESSAGE_CURRENCY; + } + if ( ! empty( array_diff( $billingAddress, $deliveryAddress ) ) ) { + $guaranteeError .= '
'.MODULE_PAYMENT_NOVALNET_FORCE_GUARANTEE_ERROR_MESSAGE_ADDRESS; + } + if ( (int) $amount < (int) $minimumAmount ) { + $guaranteeError .= '
'.sprintf(MODULE_PAYMENT_NOVALNET_FORCE_GUARANTEE_ERROR_MESSAGE_AMOUNT, str_replace('.', ',', $minimumAmount/100) .' '. $order['info']['currency']); + } + $errorMessage = PHP_EOL.$guaranteeError; + + return array('error', $errorMessage); + } + } + + /** + * Validate for users over 18 only + * + * @param $birthDate integer + * + * @return boolean + */ + public static function validateAge($birthDate) + { + return (empty($birthDate) || time() < strtotime('+18 years', strtotime($birthDate))); + } + + /** + * Prepare Instalment payment transaction detail comments + * + * @param $response array + * @param $payment string + * + * @return string + */ + public static function instalmentComments($response, $payment) + { + $transactionComments = ''; + if (!empty($response['next_instalment_date'])) { + if (!in_array( $response ['tid_status'], array( '91', '99' ), true ) ) { + if ($payment == 'novalnet_instalment_sepa') { + $comments .= PHP_EOL.PHP_EOL . sprintf(MODULE_PAYMENT_NOVALNET_INSTALMENT_SEPA_INFO, $response['amount'], $response['currency']); + } + $transactionComments .= MODULE_PAYMENT_NOVALNET_INSTALMENT_INFO; + $transactionComments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_PROCESSED . ( ! empty( $response ['instalment_cycles_executed'] ) ? $response ['instalment_cycles_executed'] : ( ! empty ( $response ['instalment1']['instalment_cycles_executed'] ) ? $response ['instalment1']['instalment_cycles_executed'] : '' ) ); + $transactionComments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_DUE . ( isset( $response ['due_instalment_cycles'] ) ? $response ['due_instalment_cycles'] : ( ! empty ( $response ['instalment1']['due_instalment_cycles'] ) ? $response ['instalment1']['due_instalment_cycles'] : '' ) ); + + $transactionComments .= PHP_EOL . MODULE_PAYMENT_NOVALNET_INSTALMENT_NXT_AMOUNT . ( ! empty( $response ['instalment_cycle_amount'] ) ? $response ['instalment_cycle_amount'] : $response ['amount'] ); + + if ( $response ['payment_id'] == '97' && $response['instalment_billing'] == '1' ) { + $transactionComments .= PHP_EOL . PHP_EOL . sprintf( MODULE_PAYMENT_NOVALNET_INSTALMENT_DEBIT_TEXT, $response ['amount']); + } + } + return $transactionComments; + } + return $transactionComments; + } + + /** + * Update the transaction details in novalnet table. + * + * @param $data array + * + * @return none + */ + public static function logInitialTransaction($data) + { + $payment = $data['payment']; + $sessionValue = $_SESSION['novalnet'][$payment]; + + $tableValues = array( + 'tid' => $sessionValue['tid'], + 'order_no' => $data['order_no'], + 'payment_id' => $sessionValue['payment_id'], + 'payment_type' => $data['payment'], + 'amount' => $sessionValue['amount'], + 'callback_amount' => $sessionValue['total_amount'], + 'gateway_status' => $sessionValue['gateway_status'], + 'date' => date('Y-m-d H:i:s'), + 'language' => $_SESSION['language'], + 'instalment_details' => (in_array($payment, array('novalnet_instalment_sepa', 'novalnet_instalment_invoice'))) ? $sessionValue['instalment_details'] : '' + ); + + zen_db_perform('novalnet_transaction_detail', $tableValues, "insert"); + } +} +?> diff --git a/includes/ext/novalnet/css/novalnet.css b/includes/ext/novalnet/css/novalnet.css new file mode 100644 index 0000000..dc2716a --- /dev/null +++ b/includes/ext/novalnet/css/novalnet.css @@ -0,0 +1,18 @@ + +#novalnet_instalment_table_invoice table, td, th { + border: 1px solid #907e7e !important; + text-align: left; + padding: 10px; +} + +#novalnet_instalment_table_invoice th, #novalnet_instalment_table_sepa th { + background-color:#a2a2a2; +} + +.autocomplete-items { + background: #fff; + border: 1px solid #66afe9; + position: absolute; + width: 86%; + z-index: 99; +} diff --git a/includes/ext/novalnet/install/install.sql b/includes/ext/novalnet/install/install.sql new file mode 100644 index 0000000..ecf79af --- /dev/null +++ b/includes/ext/novalnet/install/install.sql @@ -0,0 +1,20 @@ + +CREATE TABLE IF NOT EXISTS novalnet_transaction_detail ( + id int(11) AUTO_INCREMENT COMMENT 'Auto Increment ID', + tid bigint(20) unsigned COMMENT 'Novalnet Transaction Reference ID', + order_no int(11) COMMENT 'Order number from shop', + payment_id int(11) unsigned COMMENT 'Payment ID', + payment_type varchar(50) COMMENT 'Executed Payment type of this order', + amount int(11) unsigned COMMENT 'Transaction amount', + callback_amount int(11) unsigned COMMENT 'Callback amount', + gateway_status int(11) unsigned COMMENT 'Novalnet transaction status', + instalment_details text COMMENT 'Stored instalment details', + `date` datetime COMMENT 'Transaction Date for reference', + `language` varchar(10) COMMENT 'Shop language', + PRIMARY KEY (id), + KEY tid (tid), + KEY payment_type (payment_type), + KEY order_no (order_no) +) COMMENT='Novalnet Transaction History'; + +ALTER TABLE orders_status_history MODIFY comments text; diff --git a/includes/ext/novalnet/js/novalnet_admin.js b/includes/ext/novalnet/js/novalnet_admin.js new file mode 100644 index 0000000..6b003c2 --- /dev/null +++ b/includes/ext/novalnet/js/novalnet_admin.js @@ -0,0 +1,116 @@ +/* + * Novalnet API script + * By Novalnet (https://www.novalnet.de) + * Copyright (c) Novalnet + */ + +if (window.addEventListener) { + window.addEventListener("load", novalnet_admin); +} else if (window.attachEvent) { + window.attachEvent("load", novalnet_admin); +} + +function novalnet_admin() { + + jQuery('input[type="text"]').on('keyup',function(e){ + let selected_name = jQuery(this).attr('name'); + if( ! selected_name.match( /CUSTOMER_INFO/g ) && ! selected_name.match( /STYLE/g )) { + if ( this.value != '' && isNaN( this.value ) ) { + this.value = 0; + } + } + }); + //capture authorize + jQuery('#set_limit_title, #set_limit_desc').hide(); + jQuery('[name*="_ONHOLD_LIMIT]"]').hide(); + jQuery('[name*="_ONHOLD]"]').click(function () { + if (jQuery('[name*="_ONHOLD]"]').prop('checked') == true) { + jQuery('#set_limit_title, #set_limit_desc').hide(); + jQuery('[name*="_ONHOLD_LIMIT]"]').hide().val(''); + } + if (jQuery('[name*="_ONHOLD]"]').prop('checked') == false) { + jQuery('#set_limit_title, #set_limit_desc').show(); + jQuery('[name*="_ONHOLD_LIMIT]"]').show(); + } + + }); + if (jQuery('[name*="_ONHOLD]"]').prop('checked') == false) { + jQuery('#set_limit_title, #set_limit_desc').show(); + jQuery('[name*="_ONHOLD_LIMIT]"]').show(); + } + +jQuery('button[id=saveButton]').on('click', function(event){ + jQuery('input[name="configuration[MODULE_PAYMENT_NOVALNET_SEPA_PAYMENT_DUE_DATE]"]').attr('id', 'sepa_due_date'); + jQuery('input[name="configuration[MODULE_PAYMENT_NOVALNET_GUARANTEE_SEPA_PAYMENT_DUE_DATE]"]').attr('id', 'guarantee_sepa_due_date'); + performAdminValidations(event); + }); +function performAdminValidations(event) { + + if (jQuery('#sepa_due_date').val() != undefined && jQuery.trim(jQuery('#sepa_due_date').val()) != '') { + if (isNaN(jQuery('#sepa_due_date').val()) || jQuery('#sepa_due_date').val() < 2 || jQuery('#sepa_due_date').val() > 14) { + event.preventDefault(); + alert(jQuery('#sepa_due_date_error').val()); + } + } else if(jQuery('#guarantee_sepa_due_date').val() != undefined && jQuery.trim(jQuery('#guarantee_sepa_due_date').val()) != '') { + if ( isNaN(jQuery('#guarantee_sepa_due_date').val()) || jQuery('#guarantee_sepa_due_date').val() < 2 || jQuery('#guarantee_sepa_due_date').val() > 14) { + event.preventDefault(); + alert(jQuery('#sepa_due_date_error').val()); + } + } +} + +} + + +/** +* Creates Installment Select Fields +* @param config_name string +* @param id string +*/ +function create_installment_fields( config_name, id ) { + + let config_period_name = "configuration["+ config_name + "_PERIOD]"; + let config_cycle_name = "configuration["+ config_name + "_CYCLE]"; + let period_id = id + '_period'; + let cycle_id = id + '_cycle'; + + jQuery('input[name="' + config_period_name + '"]').attr('id', period_id ); + jQuery('input[name="' + config_cycle_name + '"]').attr('id', cycle_id ); + console.log( 'input[name="' + config_cycle_name + '"]' ); + + var selected_period = jQuery('#'+ period_id).val(); + var selected_instalment_cycles = jQuery('#'+ cycle_id).val() || ''; + jQuery('#'+ period_id ).replaceWith(''); + var lang = jQuery('#nn_lang').val(); + var instalment_periods = {'1M':'per month', '2M':'per 2 months', '3M':'per 3 months', '4M':'per 4 months', '6M':'per 6 months'}; + if (lang == 'de') + instalment_periods = {'1M':'pro Monate', '2M':'pro 2 Monate', '3M':'pro 3 Monate', '4M':'pro 4 Monate', '6M':'pro 6 Monate'}; + + jQuery.each(instalment_periods, function( index, value ) { + jQuery('#'+period_id).append(jQuery('