aboutsummaryrefslogtreecommitdiffstats
path: root/public/admin/model/extension/payment
diff options
context:
space:
mode:
Diffstat (limited to 'public/admin/model/extension/payment')
-rw-r--r--public/admin/model/extension/payment/amazon_login_pay.php452
-rw-r--r--public/admin/model/extension/payment/bluepay_hosted.php235
-rw-r--r--public/admin/model/extension/payment/bluepay_redirect.php228
-rw-r--r--public/admin/model/extension/payment/cardconnect.php328
-rw-r--r--public/admin/model/extension/payment/cardinity.php98
-rw-r--r--public/admin/model/extension/payment/divido.php81
-rw-r--r--public/admin/model/extension/payment/eway.php227
-rw-r--r--public/admin/model/extension/payment/firstdata.php222
-rw-r--r--public/admin/model/extension/payment/firstdata_remote.php278
-rw-r--r--public/admin/model/extension/payment/g2apay.php145
-rw-r--r--public/admin/model/extension/payment/globalpay.php265
-rw-r--r--public/admin/model/extension/payment/globalpay_remote.php260
-rw-r--r--public/admin/model/extension/payment/klarna_checkout.php226
-rw-r--r--public/admin/model/extension/payment/laybuy.php362
-rw-r--r--public/admin/model/extension/payment/pilibaba.php165
-rw-r--r--public/admin/model/extension/payment/pp_braintree.php168
-rw-r--r--public/admin/model/extension/payment/pp_express.php376
-rw-r--r--public/admin/model/extension/payment/pp_payflow_iframe.php136
-rw-r--r--public/admin/model/extension/payment/pp_pro_iframe.php261
-rw-r--r--public/admin/model/extension/payment/realex.php265
-rw-r--r--public/admin/model/extension/payment/realex_remote.php260
-rw-r--r--public/admin/model/extension/payment/sagepay_direct.php265
-rw-r--r--public/admin/model/extension/payment/sagepay_server.php266
-rw-r--r--public/admin/model/extension/payment/securetrading_pp.php208
-rw-r--r--public/admin/model/extension/payment/securetrading_ws.php351
-rw-r--r--public/admin/model/extension/payment/squareup.php117
-rw-r--r--public/admin/model/extension/payment/worldpay.php175
27 files changed, 6420 insertions, 0 deletions
diff --git a/public/admin/model/extension/payment/amazon_login_pay.php b/public/admin/model/extension/payment/amazon_login_pay.php
new file mode 100644
index 0000000..a89037c
--- /dev/null
+++ b/public/admin/model/extension/payment/amazon_login_pay.php
@@ -0,0 +1,452 @@
+<?php
+class ModelExtensionPaymentAmazonLoginPay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_login_pay_order` (
+ `amazon_login_pay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `amazon_order_reference_id` varchar(255) NOT NULL,
+ `amazon_authorization_id` varchar(255) NOT NULL,
+ `free_shipping` tinyint NOT NULL DEFAULT 0,
+ `date_added` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `cancel_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ KEY `amazon_order_reference_id` (`amazon_order_reference_id`),
+ PRIMARY KEY `amazon_login_pay_order_id` (`amazon_login_pay_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_login_pay_order_transaction` (
+ `amazon_login_pay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `amazon_login_pay_order_id` INT(11) NOT NULL,
+ `amazon_authorization_id` varchar(255),
+ `amazon_capture_id` varchar(255),
+ `amazon_refund_id` varchar(255),
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('authorization', 'capture', 'refund', 'cancel') DEFAULT NULL,
+ `status` ENUM('Open', 'Pending', 'Completed', 'Suspended', 'Declined', 'Closed', 'Canceled') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`amazon_login_pay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order_total_tax`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order_transaction`;");
+ }
+
+ public function deleteEvents() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('amazon_edit_capture');
+ $this->model_setting_event->deleteEventByCode('amazon_history_capture');
+ }
+
+ public function addEvents() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->addEvent('amazon_edit_capture', 'catalog/model/checkout/order/editOrder/after', 'extension/payment/amazon_login_pay/capture');
+ $this->model_setting_event->addEvent('amazon_history_capture', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/payment/amazon_login_pay/capture');
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['amazon_login_pay_order_id'], $qry->row['currency_code']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function cancel($amazon_login_pay_order) {
+ $total_captured = $this->getTotalCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ if (!empty($amazon_login_pay_order) && $total_captured == 0) {
+
+ $cancel_response = array();
+ $cancel_paramter_data = array();
+
+ $cancel_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $cancel_details = $this->offAmazon('CancelOrderReference', $cancel_paramter_data);
+ $cancel_details_xml = simplexml_load_string($cancel_details['ResponseBody']);
+ $this->logger($cancel_details_xml);
+ if (isset($cancel_details_xml->Error)) {
+ $cancel_response['status'] = 'Error';
+ $cancel_response['status_detail'] = (string)$cancel_details_xml->Error->Code . ': ' . (string)$cancel_details_xml->Error->Message;
+ } else {
+ $cancel_response['status'] = 'Completed';
+ }
+ return $cancel_response;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCancelStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `cancel_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function hasOpenAuthorization($transactions) {
+ foreach ($transactions as $transaction) {
+ if ($transaction['type'] == 'authorization' && $transaction['status'] == 'Open') {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function capture($amazon_login_pay_order, $amount) {
+ $total_captured = $this->getTotalCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ if (!empty($amazon_login_pay_order) && $amazon_login_pay_order['capture_status'] == 0 && ($total_captured + $amount <= $amazon_login_pay_order['total'])) {
+ if (!$this->hasOpenAuthorization($amazon_login_pay_order['transactions'])) {
+ $amazon_authorization = $this->authorize($amazon_login_pay_order, $amount);
+ if (isset($amazon_authorization['AmazonAuthorizationId'])) {
+ $amazon_authorization_id = $amazon_authorization['AmazonAuthorizationId'];
+ } else {
+ return $amazon_authorization;
+ }
+ } else {
+ $amazon_authorization_id = $amazon_login_pay_order['amazon_authorization_id'];
+ }
+
+ $capture_paramter_data = array();
+ $capture_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $capture_paramter_data['AmazonAuthorizationId'] = $amazon_authorization_id;
+ $capture_paramter_data['CaptureAmount.Amount'] = $amount;
+ $capture_paramter_data['CaptureAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $capture_paramter_data['CaptureReferenceId'] = 'capture_' . mt_rand();
+ $capture_paramter_data['TransactionTimeout'] = 0;
+ $capture_details = $this->offAmazon('Capture', $capture_paramter_data);
+
+ $capture_response = $this->validateResponse('Capture', $capture_details);
+ $capture_response['AmazonAuthorizationId'] = $amazon_authorization_id;
+ return $capture_response;
+ } else {
+ return false;
+ }
+ }
+
+ private function authorize($amazon_login_pay_order, $amount) {
+ $authorize_paramter_data = array();
+ $authorize_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $authorize_paramter_data['AuthorizationAmount.Amount'] = $amount;
+ $authorize_paramter_data['AuthorizationAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $authorize_paramter_data['AuthorizationReferenceId'] = 'auth_' . mt_rand();
+ $authorize_paramter_data['TransactionTimeout'] = 0;
+ $authorize_details = $this->offAmazon('Authorize', $authorize_paramter_data);
+
+ return $this->validateResponse('Authorize', $authorize_details);
+ }
+
+ public function closeOrderRef($amazon_order_reference_id) {
+ $close_paramter_data = array();
+ $close_paramter_data['AmazonOrderReferenceId'] = $amazon_order_reference_id;
+ $this->offAmazon('CloseOrderReference', $close_paramter_data);
+ $close_details = $this->offAmazon('CloseOrderReference', $close_paramter_data);
+ $this->logger($close_details);
+ }
+
+ public function updateCaptureStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `capture_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function refund($amazon_login_pay_order, $amount) {
+ if (!empty($amazon_login_pay_order) && $amazon_login_pay_order['refund_status'] != 1) {
+ $amazon_captures_remaining = $this->getUnCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ $refund_response = array();
+ $i = 0;
+ $count = count($amazon_captures_remaining);
+ for ($amount; $amount > 0 && $count > $i; $amount -= $amazon_captures_remaining[$i++]['capture_remaining']) {
+ $refund_amount = $amount;
+ if ($amazon_captures_remaining[$i]['capture_remaining'] <= $amount) {
+ $refund_amount = $amazon_captures_remaining[$i]['capture_remaining'];
+ }
+
+ $refund_paramter_data = array();
+ $refund_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $refund_paramter_data['AmazonCaptureId'] = $amazon_captures_remaining[$i]['amazon_capture_id'];
+ $refund_paramter_data['RefundAmount.Amount'] = $refund_amount;
+ $refund_paramter_data['RefundAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $refund_paramter_data['RefundReferenceId'] = 'refund_' . mt_rand();
+ $refund_paramter_data['TransactionTimeout'] = 0;
+ $refund_details = $this->offAmazon('Refund', $refund_paramter_data);
+ $refund_response[$i] = $this->validateResponse('Refund', $refund_details);
+ $refund_response[$i]['amazon_authorization_id'] = $amazon_captures_remaining[$i]['amazon_authorization_id'];
+ $refund_response[$i]['amazon_capture_id'] = $amazon_captures_remaining[$i]['amazon_capture_id'];
+ $refund_response[$i]['amount'] = $refund_amount;
+ }
+
+ return $refund_response;
+ } else {
+ return false;
+ }
+ }
+
+ public function getUnCaptured($amazon_login_pay_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE (`type` = 'refund' OR `type` = 'capture') AND `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' ORDER BY `date_added`");
+ $uncaptured = array();
+ foreach ($qry->rows as $row) {
+ $uncaptured[$row['amazon_capture_id']]['amazon_authorization_id'] = $row['amazon_authorization_id'];
+ $uncaptured[$row['amazon_capture_id']]['amazon_capture_id'] = $row['amazon_capture_id'];
+ if (isset($uncaptured[$row['amazon_capture_id']]['capture_remaining'])) {
+ $uncaptured[$row['amazon_capture_id']]['capture_remaining'] += $row['amount'];
+ } else {
+ $uncaptured[$row['amazon_capture_id']]['capture_remaining'] = $row['amount'];
+ }
+
+ if ($uncaptured[$row['amazon_capture_id']]['capture_remaining'] == 0) {
+ unset($uncaptured[$row['amazon_capture_id']]);
+ }
+ }
+ return array_values($uncaptured);
+ }
+
+ public function updateRefundStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `refund_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function getCapturesRemaining($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND capture_remaining != '0' ORDER BY `date_added`");
+ if ($query->num_rows) {
+ return $query->rows;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($amazon_login_pay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' ORDER BY `date_added` DESC");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, true, true);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($amazon_login_pay_order_id, $type, $status, $total, $amazon_authorization_id = null, $amazon_capture_id = null, $amazon_refund_id = null) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "amazon_login_pay_order_transaction` SET `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "',`amazon_authorization_id` = '" . $this->db->escape($amazon_authorization_id) . "',`amazon_capture_id` = '" . $this->db->escape($amazon_capture_id) . "',`amazon_refund_id` = '" . $this->db->escape($amazon_refund_id) . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "', `status` = '" . $this->db->escape($status) . "'");
+ }
+
+ public function updateAuthorizationStatus($amazon_authorization_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order_transaction` SET `status` = '" . $this->db->escape($status) . "' WHERE `amazon_authorization_id`='" . $this->db->escape($amazon_authorization_id) . "' AND `type`='authorization'");
+ }
+
+ public function isOrderInState($order_reference_id, $states = array()) {
+ return in_array((string)$this->fetchOrder($order_reference_id)->OrderReferenceStatus->State, $states);
+ }
+
+ public function fetchOrder($order_reference_id) {
+ $order = $this->offAmazon("GetOrderReferenceDetails", array(
+ 'AmazonOrderReferenceId' => $order_reference_id
+ ));
+
+ $responseBody = $order['ResponseBody'];
+
+ $details_xml = simplexml_load_string($responseBody);
+
+ return $details_xml
+ ->GetOrderReferenceDetailsResult
+ ->OrderReferenceDetails;
+ }
+
+ public function getTotalCaptured($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND (`type` = 'capture' OR `type` = 'refund') AND (`status` = 'Completed' OR `status` = 'Closed')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function validateDetails($data) {
+ $validate_paramter_data = array();
+ $validate_paramter_data['AWSAccessKeyId'] = $data['payment_amazon_login_pay_access_key'];
+ $validate_paramter_data['SellerId'] = $data['payment_amazon_login_pay_merchant_id'];
+ $validate_paramter_data['AmazonOrderReferenceId'] = 'validate details';
+ $validate_details = $this->offAmazon('GetOrderReferenceDetails', $validate_paramter_data);
+ $validate_response = $this->validateResponse('GetOrderReferenceDetails', $validate_details, true);
+ if($validate_response['error_code'] && $validate_response['error_code'] != 'InvalidOrderReferenceId'){
+ return $validate_response;
+ }
+ }
+
+ public function offAmazon($Action, $parameter_data, $post_data = array()) {
+ if(!empty($post_data)){
+ $merchant_id = $post_data['payment_amazon_login_pay_merchant_id'];
+ $access_key = $post_data['payment_amazon_login_pay_access_key'];
+ $access_secret = $post_data['payment_amazon_login_pay_access_secret'];
+ $test = $post_data['payment_amazon_login_pay_test'];
+ $payment_region = $post_data['payment_amazon_login_pay_payment_region'];
+ } else {
+ $merchant_id = $this->config->get('payment_amazon_login_pay_merchant_id');
+ $access_key = $this->config->get('payment_amazon_login_pay_access_key');
+ $access_secret = $this->config->get('payment_amazon_login_pay_access_secret');
+ $test = $this->config->get('payment_amazon_login_pay_test');
+ $payment_region = $this->config->get('payment_amazon_login_pay_payment_region');
+
+ }
+
+ if ($test == 'sandbox') {
+ if ($payment_region == 'USD') {
+ $url = 'https://mws.amazonservices.com/OffAmazonPayments_Sandbox/2013-01-01/';
+ } else {
+ $url = 'https://mws-eu.amazonservices.com/OffAmazonPayments_Sandbox/2013-01-01/';
+ }
+ } else {
+ if ($payment_region == 'USD') {
+ $url = 'https://mws.amazonservices.com/OffAmazonPayments/2013-01-01/';
+ } else {
+ $url = 'https://mws-eu.amazonservices.com/OffAmazonPayments/2013-01-01/';
+ }
+ }
+
+ $parameters = array();
+ $parameters['AWSAccessKeyId'] = $access_key;
+ $parameters['Action'] = $Action;
+ $parameters['SellerId'] = $merchant_id;
+ $parameters['SignatureMethod'] = 'HmacSHA256';
+ $parameters['SignatureVersion'] = 2;
+ $parameters['Timestamp'] = date('c', time());
+ $parameters['Version'] = '2013-01-01';
+ foreach ($parameter_data as $k => $v) {
+ $parameters[$k] = $v;
+ }
+
+ $query = $this->calculateStringToSignV2($parameters, $url);
+
+ $parameters['Signature'] = base64_encode(hash_hmac('sha256', $query, $access_secret, true));
+
+ return $this->sendCurl($url, $parameters);
+ }
+
+ private function validateResponse($action, $details, $skip_logger = false) {
+ $details_xml = simplexml_load_string($details['ResponseBody']);
+ if (!$skip_logger) {
+ $this->logger($details_xml);
+ }
+ switch ($action) {
+ case 'Authorize':
+ $result = 'AuthorizeResult';
+ $details = 'AuthorizationDetails';
+ $status = 'AuthorizationStatus';
+ $amazon_id = 'AmazonAuthorizationId';
+ break;
+ case 'Capture':
+ $result = 'CaptureResult';
+ $details = 'CaptureDetails';
+ $status = 'CaptureStatus';
+ $amazon_id = 'AmazonCaptureId';
+ break;
+ case 'Refund':
+ $result = 'RefundResult';
+ $details = 'RefundDetails';
+ $status = 'RefundStatus';
+ $amazon_id = 'AmazonRefundId';
+ }
+
+ $details_xml->registerXPathNamespace('m', 'http://mws.amazonservices.com/schema/OffAmazonPayments/2013-01-01');
+ $error_set = $details_xml->xpath('//m:ReasonCode');
+
+ if (isset($details_xml->Error)) {
+ $response['status'] = 'Error';
+ $response['error_code'] = (string)$details_xml->Error->Code;
+ $response['status_detail'] = (string)$details_xml->Error->Code . ': ' . (string)$details_xml->Error->Message;
+ } elseif (!empty($error_set)) {
+ $response['status'] = (string)$details_xml->$result->$details->$status->State;
+ $response['status_detail'] = (string)$details_xml->$result->$details->$status->ReasonCode;
+ } else {
+ $response['status'] = (string)$details_xml->$result->$details->$status->State;
+ $response[$amazon_id] = (string)$details_xml->$result->$details->$amazon_id;
+ }
+
+ return $response;
+ }
+
+ public function sendCurl($url, $parameters) {
+ $query = $this->getParametersAsString($parameters);
+
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $query);
+ curl_setopt($curl, CURLOPT_HEADER, true);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+ $response = curl_exec($curl);
+ curl_close($curl);
+
+ list($other, $responseBody) = explode("\r\n\r\n", $response, 2);
+ $other = preg_split("/\r\n|\n|\r/", $other);
+
+ list($protocol, $code, $text) = explode(' ', trim(array_shift($other)), 3);
+ return array('status' => (int)$code, 'ResponseBody' => $responseBody);
+ }
+
+ private function getParametersAsString(array $parameters) {
+ $queryParameters = array();
+ foreach ($parameters as $key => $value) {
+ $queryParameters[] = $key . '=' . $this->urlencode($value);
+ }
+ return implode('&', $queryParameters);
+ }
+
+ private function calculateStringToSignV2(array $parameters, $url) {
+ $data = 'POST';
+ $data .= "\n";
+ $endpoint = parse_url($url);
+ $data .= $endpoint['host'];
+ $data .= "\n";
+ $uri = array_key_exists('path', $endpoint) ? $endpoint['path'] : null;
+ if (!isset($uri)) {
+ $uri = "/";
+ }
+ $uriencoded = implode("/", array_map(array($this, "urlencode"), explode("/", $uri)));
+ $data .= $uriencoded;
+ $data .= "\n";
+ uksort($parameters, 'strcmp');
+ $data .= $this->getParametersAsString($parameters);
+ return $data;
+ }
+
+ private function urlencode($value) {
+ return str_replace('%7E', '~', rawurlencode($value));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_amazon_login_pay_debug') == 1) {
+ $log = new Log('amazon_login_pay_admin.log');
+ $backtrace = debug_backtrace();
+ $class = isset($backtrace[6]['class']) ? $backtrace[6]['class'] . '::' : '';
+ $log->write('Origin: ' . $class . $backtrace[6]['function']);
+ $log->write(!is_string($message) ? print_r($message, true) : $message);
+ unset($log);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/bluepay_hosted.php b/public/admin/model/extension/payment/bluepay_hosted.php
new file mode 100644
index 0000000..d1a85ac
--- /dev/null
+++ b/public/admin/model/extension/payment/bluepay_hosted.php
@@ -0,0 +1,235 @@
+<?php
+class ModelExtensionPaymentBluePayHosted extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_order` (
+ `bluepay_hosted_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_id` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT 0,
+ `void_status` INT(1) DEFAULT 0,
+ `rebate_status` INT(1) DEFAULT 0,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_hosted_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_order_transaction` (
+ `bluepay_hosted_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `bluepay_hosted_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_hosted_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_card`;");
+ }
+
+ public function void($order_id) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['release_status'] == 1) {
+
+ $void_data = array();
+
+ $void_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $void_data["TRANSACTION_TYPE"] = 'VOID';
+ $void_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $void_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+
+ $void_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $void_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $void_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $void_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $void_data['MERCHANT'] . $void_data["TRANSACTION_TYPE"] . $void_data["RRNO"] . $void_data["MODE"];
+
+ $void_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $this->logger('$void_data:\r\n' . print_r($void_data, 1));
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($bluepay_hosted_order_id, $status) {
+ $this->logger('$bluepay_hosted_order_id:\r\n' . print_r($bluepay_hosted_order_id, 1));
+ $this->logger('$status:\r\n' . print_r($status, 1));
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `void_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($bluepay_hosted_order['bluepay_hosted_order_id']);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['release_status'] == 0 && ($total_released + $amount <= $bluepay_hosted_order['total'])) {
+ $release_data = array();
+
+ $release_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $release_data["TRANSACTION_TYPE"] = 'CAPTURE';
+ $release_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $release_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+
+ $release_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $release_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $release_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $release_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $release_data['MERCHANT'] . $release_data["TRANSACTION_TYPE"] . $release_data["RRNO"] . $release_data["MODE"];
+
+ $release_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($bluepay_hosted_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `release_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['rebate_status'] != 1) {
+ $rebate_data = array();
+
+ $rebate_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $rebate_data["TRANSACTION_TYPE"] = 'REFUND';
+ $rebate_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $rebate_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+ $rebate_data["AMOUNT"] = $amount;
+ $rebate_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $rebate_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $rebate_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $rebate_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $rebate_data['MERCHANT'] . $rebate_data["TRANSACTION_TYPE"] . $rebate_data['AMOUNT'] . $rebate_data["RRNO"] . $rebate_data["MODE"];
+
+ $rebate_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $rebate_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($bluepay_hosted_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `rebate_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function updateTransactionId($bluepay_hosted_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `transaction_id` = '" . (int)$transaction_id . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_hosted_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['bluepay_hosted_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($bluepay_hosted_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($bluepay_hosted_order_id, $type, $total) {
+ $this->logger('$type:\r\n' . print_r($type, 1));
+ $this->logger('$total:\r\n' . print_r($total, 1));
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "bluepay_hosted_order_transaction` SET `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($bluepay_hosted_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($bluepay_hosted_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $post_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
+
+ $response_data = curl_exec($curl);
+
+ curl_close($curl);
+
+ return json_decode($response_data, true);
+ }
+
+ public function adminCallback() {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->request->get));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_bluepay_hosted_debug') == 1) {
+ $log = new Log('bluepay_hosted.log');
+ $log->write($message);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/bluepay_redirect.php b/public/admin/model/extension/payment/bluepay_redirect.php
new file mode 100644
index 0000000..e6df201
--- /dev/null
+++ b/public/admin/model/extension/payment/bluepay_redirect.php
@@ -0,0 +1,228 @@
+<?php
+class ModelExtensionPaymentBluepayredirect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_order` (
+ `bluepay_redirect_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_id` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT 0,
+ `void_status` INT(1) DEFAULT 0,
+ `rebate_status` INT(1) DEFAULT 0,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_redirect_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_order_transaction` (
+ `bluepay_redirect_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `bluepay_redirect_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_redirect_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_card`;");
+ }
+
+ public function void($order_id) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['release_status'] == 1) {
+
+ $void_data = array();
+
+ $void_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $void_data["TRANSACTION_TYPE"] = 'VOID';
+ $void_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $void_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+
+ $void_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $void_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $void_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $void_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $void_data['MERCHANT'] . $void_data["TRANSACTION_TYPE"] . $void_data["RRNO"] . $void_data["MODE"];
+
+ $void_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `void_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($bluepay_redirect_order['bluepay_redirect_order_id']);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['release_status'] == 0 && ($total_released + $amount <= $bluepay_redirect_order['total'])) {
+ $release_data = array();
+
+ $release_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $release_data["TRANSACTION_TYPE"] = 'CAPTURE';
+ $release_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $release_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+ $release_data["AMOUNT"] = $amount;
+ $release_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $release_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $release_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $release_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $release_data['MERCHANT'] . $release_data["TRANSACTION_TYPE"] . $release_data["AMOUNT"] . $release_data["RRNO"] . $release_data["MODE"];
+
+ $release_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `release_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['rebate_status'] != 1) {
+ $rebate_data = array();
+
+ $rebate_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $rebate_data["TRANSACTION_TYPE"] = 'REFUND';
+ $rebate_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $rebate_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+ $rebate_data["AMOUNT"] = $amount;
+ $rebate_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $rebate_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $rebate_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $rebate_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $rebate_data['MERCHANT'] . $rebate_data["TRANSACTION_TYPE"] . $rebate_data['AMOUNT'] . $rebate_data["RRNO"] . $rebate_data["MODE"];
+
+ $rebate_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $rebate_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `rebate_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function updateTransactionId($bluepay_redirect_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `transaction_id` = '" . (int)$transaction_id . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_redirect_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['bluepay_redirect_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($bluepay_redirect_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($bluepay_redirect_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "bluepay_redirect_order_transaction` SET `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($bluepay_redirect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($bluepay_redirect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $post_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
+
+ $response_data = curl_exec($curl);
+ curl_close($curl);
+
+ return json_decode($response_data, true);
+ }
+
+ public function callback() {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->request->get));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_bluepay_redirect_debug') == 1) {
+ $log = new Log('bluepay_redirect.log');
+ $log->write($message);
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/cardconnect.php b/public/admin/model/extension/payment/cardconnect.php
new file mode 100644
index 0000000..4cb4b60
--- /dev/null
+++ b/public/admin/model/extension/payment/cardconnect.php
@@ -0,0 +1,328 @@
+<?php
+class ModelExtensionPaymentCardConnect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_card` (
+ `cardconnect_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `cardconnect_order_id` INT(11) NOT NULL DEFAULT '0',
+ `customer_id` INT(11) NOT NULL DEFAULT '0',
+ `profileid` VARCHAR(16) NOT NULL DEFAULT '',
+ `token` VARCHAR(19) NOT NULL DEFAULT '',
+ `type` VARCHAR(50) NOT NULL DEFAULT '',
+ `account` VARCHAR(4) NOT NULL DEFAULT '',
+ `expiry` VARCHAR(4) NOT NULL DEFAULT '',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_card_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_order` (
+ `cardconnect_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL DEFAULT '0',
+ `customer_id` INT(11) NOT NULL DEFAULT '0',
+ `payment_method` VARCHAR(255) NOT NULL DEFAULT '',
+ `retref` VARCHAR(12) NOT NULL DEFAULT '',
+ `authcode` VARCHAR(6) NOT NULL DEFAULT '',
+ `currency_code` VARCHAR(3) NOT NULL DEFAULT '',
+ `total` DECIMAL(10, 2) NOT NULL DEFAULT '0.00',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_order_transaction` (
+ `cardconnect_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `cardconnect_order_id` INT(11) NOT NULL DEFAULT '0',
+ `type` VARCHAR(50) NOT NULL DEFAULT '',
+ `retref` VARCHAR(12) NOT NULL DEFAULT '',
+ `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0.00',
+ `status` VARCHAR(255) NOT NULL DEFAULT '',
+ `date_modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_card`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_order`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_order_transaction`");
+
+ $this->log('Module uninstalled');
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardconnect_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($query->num_rows) {
+ $order = $query->row;
+
+ $order['transactions'] = $this->getTransactions($order['cardconnect_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($cardconnect_order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardconnect_order_transaction` WHERE `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "'");
+
+ if ($query->num_rows) {
+ return $query->rows;
+ } else {
+ return array();
+ }
+ }
+
+ public function getTotalCaptured($cardconnect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "cardconnect_order_transaction` WHERE `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function inquire($order_info, $retref) {
+ $this->log('Posting inquire to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/inquire/' . $retref . '/' . $this->config->get('payment_cardconnect_merchant_id');
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function capture($order_info, $amount) {
+ $this->load->model('sale/order');
+
+ $this->log('Posting capture to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $order = $this->model_sale_order->getOrder($order_info['order_id']);
+
+ $totals = $this->model_sale_order->getOrderTotals($order_info['order_id']);
+
+ $shipping_cost = '';
+
+ foreach($totals as $total) {
+ if ($total['code'] == 'shipping') {
+ $shipping_cost = $total['value'];
+ }
+ }
+
+ $products = $this->model_sale_order->getOrderProducts($order_info['order_id']);
+
+ $items = array();
+
+ $i = 1;
+
+ foreach ($products as $product) {
+ $items[] = array(
+ 'lineno' => $i,
+ 'material' => '',
+ 'description' => $product['name'],
+ 'upc' => '',
+ 'quantity' => $product['quantity'],
+ 'uom' => '',
+ 'unitcost' => $product['price'],
+ 'netamnt' => $product['total'],
+ 'taxamnt' => $product['tax'],
+ 'discamnt' => ''
+ );
+
+ $i++;
+ }
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'retref' => $order_info['retref'],
+ 'authcode' => $order_info['authcode'],
+ 'ponumber' => $order_info['order_id'],
+ 'amount' => round(floatval($amount), 2, PHP_ROUND_HALF_DOWN),
+ 'currency' => $order_info['currency_code'],
+ 'frtamnt' => $shipping_cost,
+ 'dutyamnt' => '',
+ 'orderdate' => '',
+ 'shiptozip' => $order['shipping_postcode'],
+ 'shipfromzip' => '',
+ 'shiptocountry' => $order['shipping_iso_code_2'],
+ 'Items' => $items
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/capture';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function refund($order_info, $amount) {
+ $this->log('Posting refund to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'amount' => round(floatval($amount), 2, PHP_ROUND_HALF_DOWN),
+ 'currency' => $order_info['currency_code'],
+ 'retref' => $order_info['retref']
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/refund';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function void($order_info, $retref) {
+ $this->log('Posting void to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'amount' => 0,
+ 'currency' => $order_info['currency_code'],
+ 'retref' => $retref
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/void';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function updateTransactionStatusByRetref($retref, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "cardconnect_order_transaction` SET `status` = '" . $this->db->escape($status) . "', `date_modified` = NOW() WHERE `retref` = '" . $this->db->escape($retref) . "'");
+ }
+
+ public function addTransaction($cardconnect_order_id, $type, $retref, $amount, $status) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "cardconnect_order_transaction` SET `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "', `type` = '" . $this->db->escape($type) . "', `retref` = '" . $this->db->escape($retref) . "', `amount` = '" . (float)$amount . "', `status` = '" . $this->db->escape($status) . "', `date_modified` = NOW(), `date_added` = NOW()");
+ }
+
+ public function log($data) {
+ if ($this->config->get('cardconnect_logging')) {
+ $log = new Log('cardconnect.log');
+
+ $log->write($data);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/cardinity.php b/public/admin/model/extension/payment/cardinity.php
new file mode 100644
index 0000000..81ee76a
--- /dev/null
+++ b/public/admin/model/extension/payment/cardinity.php
@@ -0,0 +1,98 @@
+<?php
+use Cardinity\Client;
+use Cardinity\Method\Payment;
+use Cardinity\Method\Refund;
+
+class ModelExtensionPaymentCardinity extends Model {
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardinity_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function createClient($credentials) {
+ return Client::create(array(
+ 'consumerKey' => $credentials['key'],
+ 'consumerSecret' => $credentials['secret'],
+ ));
+ }
+
+ public function verifyCredentials($client) {
+ $method = new Payment\GetAll(10);
+
+ try {
+ $client->call($method);
+
+ return true;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getPayment($client, $payment_id) {
+ $method = new Payment\Get($payment_id);
+
+ try {
+ $payment = $client->call($method);
+
+ return $payment;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getRefunds($client, $payment_id) {
+ $method = new Refund\GetAll($payment_id);
+
+ try {
+ $refunds = $client->call($method);
+
+ return $refunds;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function refundPayment($client, $payment_id, $amount, $description) {
+ $method = new Refund\Create($payment_id, $amount, $description);
+
+ try {
+ $refund = $client->call($method);
+
+ return $refund;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function log($data) {
+ if ($this->config->get('payment_cardinity_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('cardinity.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardinity_order` (
+ `cardinity_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `payment_id` VARCHAR(255),
+ PRIMARY KEY (`cardinity_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardinity_order`;");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/divido.php b/public/admin/model/extension/payment/divido.php
new file mode 100644
index 0000000..b8c6116
--- /dev/null
+++ b/public/admin/model/extension/payment/divido.php
@@ -0,0 +1,81 @@
+<?php
+class ModelExtensionPaymentDivido extends Model {
+ const CACHE_KEY_PLANS = 'divido_plans';
+
+ public function getAllPlans() {
+ if ($plans = $this->cache->get(self::CACHE_KEY_PLANS)) {
+ // OpenCart 2.1 decodes json objects to associative arrays so we
+ // need to make sure we're getting a list of simple objects back.
+ $plans = array_map(function ($plan) {
+ return (object)$plan;
+ }, $plans);
+
+ return $plans;
+ }
+
+ $api_key = $this->config->get('payment_divido_api_key');
+ if (!$api_key) {
+ throw new Exception("No Divido api-key defined");
+ }
+
+ Divido::setMerchant($api_key);
+
+ $response = Divido_Finances::all();
+ if ($response->status != 'ok') {
+ throw new Exception("Can't get list of finance plans from Divido!");
+ }
+
+ $plans = $response->finances;
+
+ // OpenCart 2.1 switched to json for their file storage cache, so
+ // we need to convert to a simple object.
+ $plans_plain = array();
+ foreach ($plans as $plan) {
+ $plan_copy = new stdClass();
+ $plan_copy->id = $plan->id;
+ $plan_copy->text = $plan->text;
+ $plan_copy->country = $plan->country;
+ $plan_copy->min_amount = $plan->min_amount;
+ $plan_copy->min_deposit = $plan->min_deposit;
+ $plan_copy->max_deposit = $plan->max_deposit;
+ $plan_copy->interest_rate = $plan->interest_rate;
+ $plan_copy->deferral_period = $plan->deferral_period;
+ $plan_copy->agreement_duration = $plan->agreement_duration;
+
+ $plans_plain[] = $plan_copy;
+ }
+
+ $this->cache->set(self::CACHE_KEY_PLANS, $plans_plain);
+
+ return $plans_plain;
+ }
+
+ public function getLookupByOrderId($order_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "divido_lookup` WHERE `order_id` = " . (int)$order_id);
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "divido_product` (
+ `product_id` INT(11) NOT NULL,
+ `display` CHAR(7) NOT NULL,
+ `plans` text,
+ PRIMARY KEY (`product_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "divido_lookup` (
+ `order_id` INT(11) NOT NULL,
+ `salt` CHAR(64) NOT NULL,
+ `proposal_id` CHAR(40),
+ `application_id` CHAR(40),
+ `deposit_amount` NUMERIC(6,2),
+ PRIMARY KEY (`order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "divido_product`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "divido_lookup`;");
+ }
+}
diff --git a/public/admin/model/extension/payment/eway.php b/public/admin/model/extension/payment/eway.php
new file mode 100644
index 0000000..070a8d5
--- /dev/null
+++ b/public/admin/model/extension/payment/eway.php
@@ -0,0 +1,227 @@
+<?php
+
+class ModelExtensionPaymentEway extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_order` (
+ `eway_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `transaction_id` VARCHAR(24) NOT NULL,
+ `debug_data` TEXT,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ PRIMARY KEY (`eway_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_transactions` (
+ `eway_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `eway_order_id` int(11) NOT NULL,
+ `transaction_id` VARCHAR(24) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'refund', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`eway_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ //$this->model_setting_setting->deleteSetting($this->request->get['extension']);
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_transactions`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_card`;");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "eway_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['eway_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function addRefundRecord($order, $result) {
+ $transaction_id = $result->TransactionID;
+ $total_amount = $result->Refund->TotalAmount / 100;
+ $refund_amount = $order['refund_amount'] + $total_amount;
+
+ if (isset($order['refund_transaction_id']) && !empty($order['refund_transaction_id'])) {
+ $order['refund_transaction_id'] .= ',';
+ }
+ $order['refund_transaction_id'] .= $transaction_id;
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `modified` = NOW(), refund_amount = '" . (double)$refund_amount . "', `refund_transaction_id` = '" . $this->db->escape($order['refund_transaction_id']) . "' WHERE eway_order_id = '" . $order['eway_order_id'] . "'");
+ }
+
+ public function capture($order_id, $capture_amount, $currency) {
+ $eway_order = $this->getOrder($order_id);
+
+ if ($eway_order && $capture_amount > 0 ) {
+
+ $capture_data = new stdClass();
+ $capture_data->Payment = new stdClass();
+ $capture_data->Payment->TotalAmount = (int)(number_format($capture_amount, 2, '.', '') * 100);
+ $capture_data->Payment->CurrencyCode = $currency;
+ $capture_data->TransactionID = $eway_order['transaction_id'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/CapturePayment';
+ } else {
+ $url = 'https://api.ewaypayments.com/CapturePayment';
+ }
+
+ $response = $this->sendCurl($url, $capture_data);
+
+ return json_decode($response);
+
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `capture_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function updateTransactionId($eway_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `transaction_id` = '" . $transaction_id . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function void($order_id) {
+ $eway_order = $this->getOrder($order_id);
+ if ($eway_order) {
+
+ $data = new stdClass();
+ $data->TransactionID = $eway_order['transaction_id'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/CancelAuthorisation';
+ } else {
+ $url = 'https://api.ewaypayments.com/CancelAuthorisation';
+ }
+
+ $response = $this->sendCurl($url, $data);
+
+ return json_decode($response);
+
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `void_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function refund($order_id, $refund_amount) {
+ $eway_order = $this->getOrder($order_id);
+
+ if ($eway_order && $refund_amount > 0) {
+
+ $refund_data = new stdClass();
+ $refund_data->Refund = new stdClass();
+ $refund_data->Refund->TotalAmount = (int)(number_format($refund_amount, 2, '.', '') * 100);
+ $refund_data->Refund->TransactionID = $eway_order['transaction_id'];
+ $refund_data->Refund->CurrencyCode = $eway_order['currency_code'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/Transaction/' . $eway_order['transaction_id'] . '/Refund';
+ } else {
+ $url = 'https://api.ewaypayments.com/Transaction/' . $eway_order['transaction_id'] . '/Refund';
+ }
+
+ $response = $this->sendCurl($url, $refund_data);
+
+ return json_decode($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `refund_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function sendCurl($url, $data) {
+ $ch = curl_init($url);
+
+ $eway_username = html_entity_decode($this->config->get('payment_eway_username'), ENT_QUOTES, 'UTF-8');
+ $eway_password = html_entity_decode($this->config->get('payment_eway_password'), ENT_QUOTES, 'UTF-8');
+
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
+ curl_setopt($ch, CURLOPT_USERPWD, $eway_username . ":" . $eway_password);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
+
+ $response = curl_exec($ch);
+
+ if (curl_errno($ch) != CURLE_OK) {
+ $response = new stdClass();
+ $response->Errors = "POST Error: " . curl_error($ch) . " URL: $url";
+ $response = json_encode($response);
+ } else {
+ $info = curl_getinfo($ch);
+ if ($info['http_code'] == 401 || $info['http_code'] == 404) {
+ $response = new stdClass();
+ $response->Errors = "Please check the API Key and Password";
+ $response = json_encode($response);
+ }
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ private function getTransactions($eway_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($eway_order_id, $transactionid, $type, $total, $currency) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "eway_transactions` SET `eway_order_id` = '" . (int)$eway_order_id . "', `created` = NOW(), `transaction_id` = '" . $this->db->escape($transactionid) . "', `type` = '" . $this->db->escape($type) . "', `amount` = '" . $this->currency->format($total, $currency, false, false) . "'");
+ }
+
+ public function getTotalCaptured($eway_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "' AND `type` = 'payment' ");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($eway_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "' AND `type` = 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/firstdata.php b/public/admin/model/extension/payment/firstdata.php
new file mode 100644
index 0000000..bac5b8e
--- /dev/null
+++ b/public/admin/model/extension/payment/firstdata.php
@@ -0,0 +1,222 @@
+<?php
+class ModelExtensionPaymentFirstdata extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_order` (
+ `firstdata_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `tdate` DATETIME NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_order_transaction` (
+ `firstdata_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `firstdata_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_card` (
+ `firstdata_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `digits` CHAR(25) NOT NULL,
+ `expire_month` INT(2) NOT NULL,
+ `expire_year` INT(2) NOT NULL,
+ `token` CHAR(64) NOT NULL,
+ PRIMARY KEY (`firstdata_card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_card`;");
+ }
+
+ public function void($order_id) {
+ $firstdata_order = $this->getOrder($order_id);
+
+ if (!empty($firstdata_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_firstdata_merchant_id');
+ $secret = $this->config->get('payment_firstdata_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $firstdata_order['account'] . '</account>';
+ $xml .= '<orderid>' . $firstdata_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $firstdata_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $firstdata_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($firstdata_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_order` SET `void_status` = '" . (int)$status . "' WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $firstdata_order = $this->getOrder($order_id);
+
+ if (!empty($firstdata_order) && $firstdata_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_firstdata_merchant_id');
+ $secret = $this->config->get('payment_firstdata_secret');
+
+ if ($firstdata_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$firstdata_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ');
+ $this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$firstdata_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $firstdata_order['account'] . '</account>';
+ $xml .= '<orderid>' . $firstdata_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $firstdata_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $firstdata_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($firstdata_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_order` SET `capture_status` = '" . (int)$status . "' WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['firstdata_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($firstdata_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_order_transaction` WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($firstdata_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "firstdata_order_transaction` SET `firstdata_order_id` = '" . (int)$firstdata_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_firstdata_debug') == 1) {
+ $log = new Log('firstdata.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_order_transaction` WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function mapCurrency($code) {
+ $currency = array(
+ 'GBP' => 826,
+ 'USD' => 840,
+ 'EUR' => 978,
+ );
+
+ if (array_key_exists($code, $currency)) {
+ return $currency[$code];
+ } else {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/firstdata_remote.php b/public/admin/model/extension/payment/firstdata_remote.php
new file mode 100644
index 0000000..9cbd1bc
--- /dev/null
+++ b/public/admin/model/extension/payment/firstdata_remote.php
@@ -0,0 +1,278 @@
+<?php
+class ModelExtensionPaymentFirstdataRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_order` (
+ `firstdata_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `tdate` VARCHAR(30) NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_order_transaction` (
+ `firstdata_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `firstdata_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'refund', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_card` (
+ `firstdata_remote_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `digits` CHAR(4) NOT NULL,
+ `expire_month` INT(2) NOT NULL,
+ `expire_year` INT(2) NOT NULL,
+ `card_type` CHAR(15) NOT NULL,
+ `token` CHAR(64) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_card`;");
+ }
+
+ public function call($xml) {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://test.ipg-online.com/ipgapi/services");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
+ curl_setopt($ch, CURLOPT_HTTPAUTH, 'CURLAUTH_BASIC');
+ curl_setopt($ch, CURLOPT_USERPWD, $this->config->get('firstdata_remote_user_id') . ':' . $this->config->get('firstdata_remote_password'));
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
+ curl_setopt($ch, CURLOPT_CAINFO, $this->config->get('firstdata_remote_ca'));
+ curl_setopt($ch, CURLOPT_SSLCERT, $this->config->get('firstdata_remote_certificate'));
+ curl_setopt($ch, CURLOPT_SSLKEY, $this->config->get('firstdata_remote_key'));
+ curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->config->get('firstdata_remote_key_pw'));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ //curl_setopt($ch, CURLOPT_STDERR, fopen(DIR_LOGS . "/headers.txt", "w+"));
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+ $response = curl_exec ($ch);
+
+ $this->logger('Post data: ' . print_r($this->request->post, 1));
+ $this->logger('Request: ' . $xml);
+ $this->logger('Curl error #: ' . curl_errno($ch));
+ $this->logger('Curl error text: ' . curl_error($ch));
+ $this->logger('Curl response info: ' . print_r(curl_getinfo($ch), 1));
+ $this->logger('Curl response: ' . $response);
+
+ curl_close ($ch);
+
+ return $response;
+ }
+
+ public function void($order_ref, $tdate) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>void</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '<v1:TDate>' . $tdate . '</v1:TDate>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateVoidStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function capture($order_ref, $total, $currency_code) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>postAuth</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:Payment>';
+ $xml .= '<v1:ChargeTotal>' . $total . '</v1:ChargeTotal>';
+ $xml .= '<v1:Currency>' . $this->mapCurrency($currency_code) . '</v1:Currency>';
+ $xml .= '</v1:Payment>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateCaptureStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function refund($order_ref, $total, $currency_code) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>return</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:Payment>';
+ $xml .= '<v1:ChargeTotal>' . $total . '</v1:ChargeTotal>';
+ $xml .= '<v1:Currency>' . $this->mapCurrency($currency_code) . '</v1:Currency>';
+ $xml .= '</v1:Payment>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateRefundStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `refund_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['firstdata_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($firstdata_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($firstdata_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "firstdata_remote_order_transaction` SET `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('firstdata_remote_debug') == 1) {
+ $log = new Log('firstdata_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRefunded($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_order_id . "' AND 'refund'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function mapCurrency($code) {
+ $currency = array(
+ 'GBP' => 826,
+ 'USD' => 840,
+ 'EUR' => 978,
+ );
+
+ if (array_key_exists($code, $currency)) {
+ return $currency[$code];
+ } else {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/g2apay.php b/public/admin/model/extension/payment/g2apay.php
new file mode 100644
index 0000000..83ea7b8
--- /dev/null
+++ b/public/admin/model/extension/payment/g2apay.php
@@ -0,0 +1,145 @@
+<?php
+
+class ModelExtensionPaymentG2aPay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "g2apay_order` (
+ `g2apay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `g2apay_transaction_id` varchar(255) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ KEY `g2apay_transaction_id` (`g2apay_transaction_id`),
+ PRIMARY KEY `g2apay_order_id` (`g2apay_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "g2apay_order_transaction` (
+ `g2apay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `g2apay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('payment', 'refund') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`g2apay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "g2apay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "g2apay_order_transaction`;");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "g2apay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['g2apay_order_id'], $qry->row['currency_code']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTotalReleased($g2apay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function refund($g2apay_order, $amount) {
+ if (!empty($g2apay_order) && $g2apay_order['refund_status'] != 1) {
+ if ($this->config->get('payment_g2apay_environment') == 1) {
+ $url = 'https://pay.g2a.com/rest/transactions/' . $g2apay_order['g2apay_transaction_id'];
+ } else {
+ $url = 'https://www.test.pay.g2a.com/rest/transactions/' . $g2apay_order['g2apay_transaction_id'];
+ }
+
+ $refunded_amount = round($amount, 2);
+
+ $string = $g2apay_order['g2apay_transaction_id'] . $g2apay_order['order_id'] . round($g2apay_order['total'], 2) . $refunded_amount . html_entity_decode($this->config->get('payment_g2apay_secret'));
+ $hash = hash('sha256', $string);
+
+ $fields = array(
+ 'action' => 'refund',
+ 'amount' => $refunded_amount,
+ 'hash' => $hash,
+ );
+
+ return $this->sendCurl($url, $fields);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($g2apay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "g2apay_order` SET `refund_status` = '" . (int)$status . "' WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "'");
+ }
+
+ private function getTransactions($g2apay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "'");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, true, true);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($g2apay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "g2apay_order_transaction` SET `g2apay_order_id` = '" . (int)$g2apay_order_id . "',`date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalRefunded($g2apay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function sendCurl($url, $fields) {
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fields));
+
+ $auth_hash = hash('sha256', $this->config->get('payment_g2apay_api_hash') . $this->config->get('payment_g2apay_username') . html_entity_decode($this->config->get('payment_g2apay_secret')));
+ $authorization = $this->config->get('payment_g2apay_api_hash') . ";" . $auth_hash;
+ curl_setopt(
+ $curl, CURLOPT_HTTPHEADER, array(
+ "Authorization: " . $authorization
+ )
+ );
+
+ $response = json_decode(curl_exec($curl));
+
+ curl_close($curl);
+ if (is_object($response)) {
+ return (string)$response->status;
+ } else {
+ return str_replace('"', "", $response);
+ }
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_g2apay_debug') == 1) {
+ $log = new Log('g2apay.log');
+ $backtrace = debug_backtrace();
+ $log->write('Origin: ' . $backtrace[6]['class'] . '::' . $backtrace[6]['function']);
+ $log->write(print_r($message, 1));
+ }
+ }
+
+}
diff --git a/public/admin/model/extension/payment/globalpay.php b/public/admin/model/extension/payment/globalpay.php
new file mode 100644
index 0000000..a28dbb2
--- /dev/null
+++ b/public/admin/model/extension/payment/globalpay.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentGlobalpay extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_order` (
+ `globalpay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_order_transaction` (
+ `globalpay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `globalpay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `void_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `capture_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function updateForRebate($globalpay_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $globalpay_order['order_ref'];
+
+ if (empty($globalpay_order['pasref_previous'])) {
+ $pas_ref = $globalpay_order['pasref'];
+ } else {
+ $pas_ref = $globalpay_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $globalpay_order['order_ref'];
+ $pas_ref = $globalpay_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebate_hash = sha1($this->config->get('payment_globalpay_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebate_hash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `rebate_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['globalpay_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($globalpay_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($globalpay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "globalpay_order_transaction` SET `globalpay_order_id` = '" . (int)$globalpay_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_globalpay_debug') == 1) {
+ $log = new Log('globalpay.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/globalpay_remote.php b/public/admin/model/extension/payment/globalpay_remote.php
new file mode 100644
index 0000000..788e70b
--- /dev/null
+++ b/public/admin/model/extension/payment/globalpay_remote.php
@@ -0,0 +1,260 @@
+<?php
+class ModelExtensionPaymentGlobalpayRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_remote_order` (
+ `globalpay_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_remote_order_transaction` (
+ `globalpay_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `globalpay_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function updateForRebate($globalpay_remote_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $globalpay_order['order_ref'];
+
+ if (empty($globalpay_order['pasref_previous'])) {
+ $pas_ref = $globalpay_order['pasref'];
+ } else {
+ $pas_ref = $globalpay_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $globalpay_order['order_ref'];
+ $pas_ref = $globalpay_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebatehash = sha1($this->config->get('payment_globalpay_remote_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebatehash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `rebate_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['globalpay_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($globalpay_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($globalpay_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "globalpay_remote_order_transaction` SET `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_globalpay_remote_debug') == 1) {
+ $log = new Log('globalpay_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/klarna_checkout.php b/public/admin/model/extension/payment/klarna_checkout.php
new file mode 100644
index 0000000..d9e9cbc
--- /dev/null
+++ b/public/admin/model/extension/payment/klarna_checkout.php
@@ -0,0 +1,226 @@
+<?php
+use Klarna\Rest\Transport\Connector as KCConnector;
+use Klarna\Rest\Transport\ConnectorInterface as KCConnectorInterface;
+use Klarna\Rest\OrderManagement\Order as KCOrder;
+
+class ModelExtensionPaymentKlarnaCheckout extends Model {
+ public function connector($merchant_id, $secret, $url) {
+ try {
+ $connector = KCConnector::create(
+ $merchant_id,
+ $secret,
+ $url
+ );
+
+ return $connector;
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omRetrieve(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->fetch();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCancel(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->cancel();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCapture(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->createCapture($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omRefund(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->refund($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omExtendAuthorizationTime(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->extendAuthorizationTime();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omUpdateMerchantReference(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->updateMerchantReferences($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omUpdateAddress(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->updateCustomerDetails($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omReleaseAuthorization(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->releaseRemainingAuthorization();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omShippingInfo(KCConnector $connector, $order_id, $capture_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->addShippingInfo($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCustomerDetails(KCConnector $connector, $order_id, $capture_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->updateCustomerDetails($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omTriggerSendOut(KCConnector $connector, $order_id, $capture_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->triggerSendout();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getConnector($accounts, $currency) {
+ $klarna_account = false;
+ $connector = false;
+
+ if ($accounts && $currency) {
+ foreach ($accounts as $account) {
+ if ($account['currency'] == $currency) {
+ if ($account['environment'] == 'test') {
+ if ($account['api'] == 'NA') {
+ $base_url = KCConnectorInterface::NA_TEST_BASE_URL;
+ } elseif ($account['api'] == 'EU') {
+ $base_url = KCConnectorInterface::EU_TEST_BASE_URL;
+ }
+ } elseif ($account['environment'] == 'live') {
+ if ($account['api'] == 'NA') {
+ $base_url = KCConnectorInterface::NA_BASE_URL;
+ } elseif ($account['api'] == 'EU') {
+ $base_url = KCConnectorInterface::EU_BASE_URL;
+ }
+ }
+
+ $klarna_account = $account;
+ $connector = $this->connector(
+ $account['merchant_id'],
+ $account['secret'],
+ $base_url
+ );
+
+ break;
+ }
+ }
+ }
+
+ return array($klarna_account, $connector);
+ }
+
+ public function getOrder($order_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "klarna_checkout_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1")->row;
+ }
+
+ public function checkForPaymentTaxes() {
+ $query = $this->db->query("SELECT COUNT(*) AS `total` FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "tax_rule tr ON (`tr`.`tax_class_id` = `p`.`tax_class_id`) WHERE `tr`.`based` = 'payment'");
+
+ return $query->row['total'];
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "klarna_checkout_order` (
+ `klarna_checkout_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` VARCHAR(255) NOT NULL,
+ `data` text NOT NULL,
+ PRIMARY KEY (`klarna_checkout_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "klarna_checkout_order`;");
+ }
+
+ public function log($data) {
+ if ($this->config->get('klarna_checkout_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('klarna_checkout.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/laybuy.php b/public/admin/model/extension/payment/laybuy.php
new file mode 100644
index 0000000..f9689fd
--- /dev/null
+++ b/public/admin/model/extension/payment/laybuy.php
@@ -0,0 +1,362 @@
+<?php
+class ModelExtensionPaymentLaybuy extends Model {
+ public function addRevisedTransaction($data = array()) {
+ $query = $this->db->query("INSERT INTO `" . DB_PREFIX . "laybuy_revise_request` SET `laybuy_transaction_id` = '" . (int)$data['transaction_id'] . "', `type` = '" . $this->db->escape($data['type']) . "', `order_id` = '" . (int)$data['order_id'] . "', `firstname` = '" . $this->db->escape($data['firstname']) . "', `lastname` = '" . $this->db->escape($data['lastname']) . "', `address` = '" . $this->db->escape($data['address']) . "', `suburb` = '" . $this->db->escape($data['suburb']) . "', `state` = '" . $this->db->escape($data['state']) . "', `country` = '" . $this->db->escape($data['country']) . "', `postcode` = '" . $this->db->escape($data['postcode']) . "', `email` = '" . $this->db->escape($data['email']) . "', `amount` = '" . (float)$data['amount'] . "', `currency` = '" . $this->db->escape($data['currency']) . "', `downpayment` = '" . $this->db->escape($data['downpayment']) . "', `months` = '" . (int)$data['months'] . "', `downpayment_amount` = '" . (float)$data['downpayment_amount'] . "', `payment_amounts` = '" . (float)$data['payment_amounts'] . "', `first_payment_due` = '" . $this->db->escape($data['first_payment_due']) . "', `last_payment_due` = '" . $this->db->escape($data['last_payment_due']) . "', `store_id` = '" . (int)$data['store_id'] . "', `status` = '" . (int)$data['status'] . "', `report` = '" . $this->db->escape($data['report']) . "', `transaction` = '" . (int)$data['transaction'] . "', `paypal_profile_id` = '" . $this->db->escape($data['paypal_profile_id']) . "', `laybuy_ref_no` = '" . (int)$data['laybuy_ref_no'] . "', `payment_type` = '" . (int)$data['payment_type'] . "', `date_added` = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function getCustomerIdByOrderId($order_id) {
+ $query = $this->db->query("SELECT `customer_id` FROM `" . DB_PREFIX . "order` WHERE `order_id` = '" . (int)$order_id . "'");
+
+ if ($query->num_rows) {
+ return $query->row['customer_id'];
+ } else {
+ return 0;
+ }
+ }
+
+ public function getInitialPayments() {
+ $minimum = $this->config->get('payment_laybuy_min_deposit') ? $this->config->get('payment_laybuy_min_deposit') : 20;
+
+ $maximum = $this->config->get('payment_laybuy_max_deposit') ? $this->config->get('payment_laybuy_max_deposit') : 50;
+
+ $initial_payments = array();
+
+ for ($i = $minimum; $i <= $maximum; $i += 10) {
+ $initial_payments[] = $i;
+ }
+
+ return $initial_payments;
+ }
+
+ public function getMonths() {
+ $this->load->language('extension/payment/laybuy');
+
+ $max_months = $this->config->get('payment_laybuy_max_months');
+
+ if (!$max_months) {
+ $max_months = 3;
+ }
+
+ if ($max_months < 1) {
+ $max_months = 1;
+ }
+
+ $months = array();
+
+ for ($i = 1; $i <= $max_months; $i++) {
+ $months[] = array(
+ 'value' => $i,
+ 'label' => $i . ' ' . (($i > 1) ? $this->language->get('text_months') : $this->language->get('text_month'))
+ );
+ }
+
+ return $months;
+ }
+
+ public function getPayPalProfileIds() {
+ $query = $this->db->query("SELECT `paypal_profile_id` FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `status` = '1'");
+
+ return $query->rows;
+ }
+
+ public function getRevisedTransaction($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_revise_request` WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+
+ return $query->row;
+ }
+
+ public function getRemainingAmount($amount, $downpayment_amount, $payment_amounts, $transaction = 2) {
+ return $amount - ($downpayment_amount + (((int)$transaction - 2) * $payment_amounts));
+ }
+
+ public function getRevisedTransactions($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_revise_request` WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+
+ return $query->rows;
+ }
+
+ public function getStatusLabel($id) {
+ $statuses = $this->getTransactionStatuses();
+
+ foreach ($statuses as $status) {
+ if ($status['status_id'] == $id && $status['status_name'] != '') {
+ return $status['status_name'];
+
+ break;
+ }
+ }
+
+ return $id;
+ }
+
+ public function getTransaction($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+
+ return $query->row;
+ }
+
+ public function getTransactions($data = array()) {
+ $sql = "SELECT *, CONCAT(firstname, ' ', lastname) AS `customer` FROM `" . DB_PREFIX . "laybuy_transaction` `lt` WHERE 1 = 1";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "`lt`.`order_id` = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_dp_percent'])) {
+ $implode[] = "`lt`.`downpayment` = '" . (int)$data['filter_dp_percent'] . "'";
+ }
+
+ if (!empty($data['filter_months'])) {
+ $implode[] = "`lt`.`months` = '" . (int)$data['filter_months'] . "'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] = "`lt`.`status` = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(`lt`.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " AND " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'lt.order_id',
+ 'customer',
+ 'lt.amount',
+ 'lt.downpayment',
+ 'lt.months',
+ 'lt.downpayment_amount',
+ 'lt.first_payment_due',
+ 'lt.last_payment_due',
+ 'lt.status',
+ 'lt.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY order_id";
+ }
+
+ if (isset($data['order']) && ($data['order'] == 'DESC')) {
+ $sql .= " DESC";
+ } else {
+ $sql .= " ASC";
+ }
+
+ if (isset($data['sort']) && $data['sort'] != 'lt.date_added') {
+ $sql .= ", lt.date_added DESC";
+ }
+
+ if (isset($data['start']) || isset($data['limit'])) {
+ if ($data['start'] < 0) {
+ $data['start'] = 0;
+ }
+
+ if ($data['limit'] < 1) {
+ $data['limit'] = 20;
+ }
+
+ $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTransactions($data = array()) {
+ $sql = "SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "laybuy_transaction` `lt` WHERE 1 = 1";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "`lt`.`order_id` = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_dp_percent'])) {
+ $implode[] = "`lt`.`downpayment` = '" . (int)$data['filter_dp_percent'] . "'";
+ }
+
+ if (!empty($data['filter_months'])) {
+ $implode[] = "`lt`.`months` = '" . (int)$data['filter_months'] . "'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] = "`lt`.`status` = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(`lt`.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " AND " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTransactionByLayBuyRefId($laybuy_ref_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `laybuy_ref_no` = '" . (int)$laybuy_ref_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTransactionByOrderId($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `order_id` = '" . (int)$order_id . "' ORDER BY `laybuy_ref_no` DESC LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function getTransactionStatuses() {
+ $this->load->language('extension/payment/laybuy');
+
+ $transaction_statuses = array(
+ array(
+ 'status_id' => 1,
+ 'status_name' => $this->language->get('text_status_1')
+ ),
+ array(
+ 'status_id' => 5,
+ 'status_name' => $this->language->get('text_status_5')
+ ),
+ array(
+ 'status_id' => 7,
+ 'status_name' => $this->language->get('text_status_7')
+ ),
+ array(
+ 'status_id' => 50,
+ 'status_name' => $this->language->get('text_status_50')
+ ),
+ array(
+ 'status_id' => 51,
+ 'status_name' => $this->language->get('text_status_51')
+ )
+ );
+
+ return $transaction_statuses;
+ }
+
+ public function install() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "laybuy_transaction` (
+ `laybuy_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `firstname` varchar(32) NOT NULL DEFAULT '',
+ `lastname` varchar(32) NOT NULL DEFAULT '',
+ `address` text,
+ `suburb` varchar(128) NOT NULL DEFAULT '',
+ `state` varchar(128) NOT NULL DEFAULT '',
+ `country` varchar(32) NOT NULL DEFAULT '',
+ `postcode` varchar(10) NOT NULL DEFAULT '',
+ `email` varchar(96) NOT NULL DEFAULT '',
+ `amount` double NOT NULL,
+ `currency` varchar(5) NOT NULL,
+ `downpayment` double NOT NULL,
+ `months` int(11) NOT NULL,
+ `downpayment_amount` double NOT NULL,
+ `payment_amounts` double NOT NULL,
+ `first_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `last_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `store_id` int(11) NOT NULL DEFAULT '0',
+ `status` int(11) NOT NULL DEFAULT '1',
+ `report` text,
+ `transaction` int(11) NOT NULL DEFAULT '2',
+ `paypal_profile_id` varchar(250) NOT NULL DEFAULT '',
+ `laybuy_ref_no` int(11) NOT NULL DEFAULT '0',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`laybuy_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "laybuy_revise_request` (
+ `laybuy_revise_request_id` int(11) NOT NULL AUTO_INCREMENT,
+ `laybuy_transaction_id` int(11) DEFAULT '0',
+ `type` varchar(250) NOT NULL DEFAULT '',
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `firstname` varchar(32) NOT NULL DEFAULT '',
+ `lastname` varchar(32) NOT NULL DEFAULT '',
+ `address` text,
+ `suburb` varchar(128) NOT NULL DEFAULT '',
+ `state` varchar(128) NOT NULL DEFAULT '',
+ `country` varchar(32) NOT NULL DEFAULT '',
+ `postcode` varchar(10) NOT NULL DEFAULT '',
+ `email` varchar(96) NOT NULL DEFAULT '',
+ `amount` double NOT NULL,
+ `currency` varchar(5) NOT NULL,
+ `downpayment` double NOT NULL,
+ `months` int(11) NOT NULL,
+ `downpayment_amount` double NOT NULL,
+ `payment_amounts` double NOT NULL,
+ `first_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `last_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `store_id` int(11) NOT NULL DEFAULT '0',
+ `status` int(11) NOT NULL DEFAULT '1',
+ `report` text,
+ `transaction` int(11) NOT NULL DEFAULT '2',
+ `paypal_profile_id` varchar(250) NOT NULL DEFAULT '',
+ `laybuy_ref_no` int(11) NOT NULL DEFAULT '0',
+ `payment_type` tinyint(1) NOT NULL DEFAULT '1',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`laybuy_revise_request_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('laybuy', 'catalog/model/checkout/order/deleteOrder/after', 'extension/payment/laybuy/deleteOrder');
+ }
+
+ public function log($data, $step = 6) {
+ if ($this->config->get('payment_laybuy_logging')) {
+ $backtrace = debug_backtrace();
+
+ $log = new Log('laybuy.log');
+
+ $log->write('(' . $backtrace[$step]['class'] . '::' . $backtrace[$step]['function'] . ') - ' . $data);
+ }
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "laybuy_transaction`");
+
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "laybuy_revise_request`");
+
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->deleteEventByCode('laybuy');
+ }
+
+ public function updateOrderStatus($order_id, $order_status_id, $comment) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "order` SET `order_status_id` = '" . (int)$order_status_id . "', `date_modified` = NOW() WHERE `order_id` = '" . (int)$order_id . "'");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "order_history` SET `order_id` = '" . (int)$order_id . "', `order_status_id` = '" . (int)$order_status_id . "', `notify` = '0', `comment` = '" . $this->db->escape($comment) . "', `date_added` = NOW()");
+ }
+
+ public function updateRevisedTransaction($id, $data = array()) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_revise_request` SET `laybuy_transaction_id` = '" . (int)$data['transaction_id'] . "', `type` = '" . $this->db->escape($data['type']) . "', `order_id` = '" . (int)$data['order_id'] . "', `firstname` = '" . $this->db->escape($data['firstname']) . "', `lastname` = '" . $this->db->escape($data['lastname']) . "', `address` = '" . $this->db->escape($data['address']) . "', `suburb` = '" . $this->db->escape($data['suburb']) . "', `state` = '" . $this->db->escape($data['state']) . "', `country` = '" . $this->db->escape($data['country']) . "', `postcode` = '" . $this->db->escape($data['postcode']) . "', `email` = '" . $this->db->escape($data['email']) . "', `amount` = '" . (float)$data['amount'] . "', `currency` = '" . $this->db->escape($data['currency']) . "', `downpayment` = '" . $this->db->escape($data['downpayment']) . "', `months` = '" . (int)$data['months'] . "', `downpayment_amount` = '" . (float)$data['downpayment_amount'] . "', `payment_amounts` = '" . (float)$data['payment_amounts'] . "', `first_payment_due` = '" . $this->db->escape($data['first_payment_due']) . "', `last_payment_due` = '" . $this->db->escape($data['last_payment_due']) . "', `store_id` = '" . (int)$data['store_id'] . "', `status` = '" . (int)$data['status'] . "', `report` = '" . $this->db->escape($data['report']) . "', `transaction` = '" . (int)$data['transaction'] . "', `paypal_profile_id` = '" . $this->db->escape($data['paypal_profile_id']) . "', `laybuy_ref_no` = '" . (int)$data['laybuy_ref_no'] . "', `payment_type` = '" . (int)$data['payment_type'] . "', `date_added` = NOW() WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+ }
+
+ public function updateTransaction($id, $status, $report, $transaction) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_transaction` SET `status` = '" . (int)$status . "', `report` = '" . $this->db->escape($report) . "', `transaction` = '" . (int)$transaction . "' WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+ }
+
+ public function updateTransactionStatus($id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_transaction` SET `status` = '" . (int)$status . "' WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pilibaba.php b/public/admin/model/extension/payment/pilibaba.php
new file mode 100644
index 0000000..718680d
--- /dev/null
+++ b/public/admin/model/extension/payment/pilibaba.php
@@ -0,0 +1,165 @@
+<?php
+class ModelExtensionPaymentPilibaba extends Model {
+ public function install() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "pilibaba_order` (
+ `pilibaba_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `amount` double NOT NULL,
+ `fee` double NOT NULL,
+ `tracking` VARCHAR(50) NOT NULL DEFAULT '',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`pilibaba_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "pilibaba_order`");
+
+ $this->disablePiliExpress();
+
+ $this->log('Module uninstalled');
+ }
+
+ public function getCurrencies() {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, 'http://www.pilibaba.com/pilipay/getCurrency');
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ return json_decode($response, true);
+ }
+
+ public function getWarehouses() {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, 'http://www.pilibaba.com/pilipay/getAddressList');
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ return json_decode($response, true);
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "pilibaba_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($query->num_rows) {
+ return $query->row;
+ } else {
+ return false;
+ }
+ }
+
+ public function register($email, $password, $currency, $warehouse, $country, $environment) {
+ $this->log('Posting register');
+
+ if ($warehouse == 'other') {
+ $warehouse = '';
+ }
+
+ if ($warehouse) {
+ $country = '';
+ }
+
+ if ($environment == 'live') {
+ $url = 'http://en.pilibaba.com/autoRegist';
+ } else {
+ $url = 'http://preen.pilibaba.com/autoRegist';
+ }
+
+ $this->log('URL: ' . $url);
+
+ $app_secret = strtoupper(md5((($warehouse) ? $warehouse : $country) . '0210000574' . '0b8l3ww5' . $currency . $email . md5($password)));
+
+ $data = array(
+ 'platformNo' => '0210000574',
+ 'appSecret' => $app_secret,
+ 'email' => $email,
+ 'password' => md5($password),
+ 'currency' => $currency,
+ 'logistics' => $warehouse,
+ 'countryCode' => $country
+ );
+
+ $this->log('Data: ' . print_r($data, true));
+
+ $headers = array('Accept: application/json','Content-Type: application/json');
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $this->log('Response: ' . print_r($response, true));
+
+ return json_decode($response, true);
+ }
+
+ public function updateTrackingNumber($order_id, $tracking_number, $merchant_number) {
+ $this->log('Posting tracking');
+
+ $sign_msg = strtoupper(md5($order_id . $tracking_number . $merchant_number . $this->config->get('payment_pilibaba_secret_key')));
+
+ if ($this->config->get('payment_pilibaba_environment') == 'live') {
+ $url = 'https://www.pilibaba.com/pilipay/updateTrackNo';
+ } else {
+ $url = 'http://pre.pilibaba.com/pilipay/updateTrackNo';
+ }
+
+ $url .= '?orderNo=' . $order_id . '&logisticsNo=' . $tracking_number . '&merchantNo=' . $merchant_number . '&signMsg=' . $sign_msg;
+
+ $this->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "pilibaba_order` SET `tracking` = '" . $this->db->escape($tracking_number) . "' WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function enablePiliExpress() {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension` WHERE `type` = 'shipping' AND `code` = 'pilibaba'");
+
+ if (!$query->num_rows) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "extension` SET `type` = 'shipping', `code` = 'pilibaba'");
+ }
+ }
+
+ public function disablePiliExpress() {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension` WHERE `type` = 'shipping' AND `code` = 'pilibaba'");
+ }
+
+ public function log($data) {
+ if ($this->config->has('payment_pilibaba_logging') && $this->config->get('payment_pilibaba_logging')) {
+ $log = new Log('pilibaba.log');
+
+ $log->write($data);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pp_braintree.php b/public/admin/model/extension/payment/pp_braintree.php
new file mode 100644
index 0000000..af0e604
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_braintree.php
@@ -0,0 +1,168 @@
+<?php
+class ModelExtensionPaymentPPBraintree extends Model {
+ public function generateToken($gateway, $data = array()) {
+ try {
+ if ($gateway != null) {
+ $client_token = $gateway->clientToken()->generate($data);
+ } else {
+ $client_token = Braintree_ClientToken::generate($data);
+ }
+
+ return $client_token;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getTransaction($gateway, $transaction_id) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->find($transaction_id);
+ } else {
+ $transaction = Braintree_Transaction::find($transaction_id);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getTransactions($gateway, $data = array()) {
+ try {
+ if ($gateway != null) {
+ $transactions = $gateway->transaction()->search($data);
+ } else {
+ $transactions = Braintree_Transaction::search($data);
+ }
+
+ if ($transactions) {
+ return $transactions;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function voidTransaction($gateway, $transaction_id) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->void($transaction_id);
+ } else {
+ $transaction = Braintree_Transaction::void($transaction_id);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function settleTransaction($gateway, $transaction_id, $amount) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->submitForSettlement($transaction_id, $amount);
+ } else {
+ $transaction = Braintree_Transaction::submitForSettlement($transaction_id, $amount);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function refundTransaction($gateway, $transaction_id, $amount) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->refund($transaction_id, $amount);
+ } else {
+ $transaction = Braintree_Transaction::refund($transaction_id, $amount);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function verifyCredentials($gateway) {
+ try {
+ //Try API call, if no exception is thrown, the credentials are correct
+ if ($gateway != null) {
+ $client_token = $gateway->clientToken()->generate();
+ } else {
+ $client_token = Braintree_ClientToken::generate();
+ }
+
+ return $client_token;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function verifyMerchantAccount($gateway, $merchant_account_id) {
+ try {
+ //Try API call, if no exception is thrown, the above credentials are correct
+ if ($gateway != null) {
+ $merchant_account = $gateway->merchantAccount()->find($merchant_account_id);
+ } else {
+ $merchant_account = Braintree_MerchantAccount::find($merchant_account_id);
+ }
+
+ if ($merchant_account && $merchant_account->status == 'active') {
+ return $merchant_account;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function setGateway($access_token) {
+ return new Braintree_Gateway(array('accessToken' => $access_token));
+ }
+
+ public function log($data) {
+ if ($this->config->get('payment_pp_braintree_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('braintree.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/pp_express.php b/public/admin/model/extension/payment/pp_express.php
new file mode 100644
index 0000000..5c82d30
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_express.php
@@ -0,0 +1,376 @@
+<?php
+class ModelExtensionPaymentPPExpress extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order` (
+ `paypal_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` ENUM('Complete','NotComplete') DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authorization_id` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`paypal_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order_transaction` (
+ `paypal_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `paypal_order_id` int(11) NOT NULL,
+ `transaction_id` CHAR(20) NOT NULL,
+ `parent_id` CHAR(20) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `note` VARCHAR(255) NOT NULL,
+ `msgsubid` CHAR(38) NOT NULL,
+ `receipt_id` CHAR(20) NOT NULL,
+ `payment_type` ENUM('none','echeck','instant', 'refund', 'void') DEFAULT NULL,
+ `payment_status` CHAR(20) NOT NULL,
+ `pending_reason` CHAR(50) NOT NULL,
+ `transaction_entity` CHAR(50) NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `debug_data` TEXT NOT NULL,
+ `call_data` TEXT NOT NULL,
+ PRIMARY KEY (`paypal_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci
+ ");
+
+ $this->load->model('setting/setting');
+
+ $defaults = array();
+
+ // Order Status defaults
+ $defaults['payment_pp_express_canceled_reversal_status_id'] = 9;
+ $defaults['payment_pp_express_completed_status_id'] = 5;
+ $defaults['payment_pp_express_denied_status_id'] = 8;
+ $defaults['payment_pp_express_expired_status_id'] = 14;
+ $defaults['payment_pp_express_failed_status_id'] = 10;
+ $defaults['payment_pp_express_pending_status_id'] = 1;
+ $defaults['payment_pp_express_processed_status_id'] = 15;
+ $defaults['payment_pp_express_refunded_status_id'] = 11;
+ $defaults['payment_pp_express_reversed_status_id'] = 12;
+ $defaults['payment_pp_express_voided_status_id'] = 16;
+
+ $defaults['payment_pp_express_status'] = 0;
+ $defaults['payment_pp_express_currency'] = "USD";
+
+ $this->model_setting_setting->editSetting('payment_pp_express', $defaults);
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->addEvent('extension_pp_express_checkout_js', 'catalog/controller/checkout/checkout/before', 'extension/payment/pp_express/eventLoadCheckoutJs');
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order_transaction`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order`");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('extension_pp_express_checkout_js');
+ }
+
+ public function getPayPalOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_order` WHERE `order_id` = '" . (int)$order_id . "'");
+
+ return $query->row;
+ }
+
+ public function editPayPalOrderStatus($order_id, $capture_status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_order` SET `capture_status` = '" . $this->db->escape($capture_status) . "', `date_modified` = NOW() WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function addTransaction($transaction_data, $request_data = array()) {
+ if ($request_data) {
+ $serialized_data = json_encode($request_data);
+
+ $this->db->query("UPDATE " . DB_PREFIX . "paypal_order_transaction SET call_data = '" . $this->db->escape($serialized_data) . "' WHERE paypal_order_transaction_id = " . (int)$paypal_order_transaction_id . " LIMIT 1");
+ }
+
+
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_order_transaction` SET `paypal_order_id` = '" . (int)$transaction_data['paypal_order_id'] . "', `transaction_id` = '" . $this->db->escape($transaction_data['transaction_id']) . "', `parent_id` = '" . $this->db->escape($transaction_data['parent_id']) . "', `date_added` = NOW(), `note` = '" . $this->db->escape($transaction_data['note']) . "', `msgsubid` = '" . $this->db->escape($transaction_data['msgsubid']) . "', `receipt_id` = '" . $this->db->escape($transaction_data['receipt_id']) . "', `payment_type` = '" . $this->db->escape($transaction_data['payment_type']) . "', `payment_status` = '" . $this->db->escape($transaction_data['payment_status']) . "', `pending_reason` = '" . $this->db->escape($transaction_data['pending_reason']) . "', `transaction_entity` = '" . $this->db->escape($transaction_data['transaction_entity']) . "', `amount` = '" . (float)$transaction_data['amount'] . "', `debug_data` = '" . $this->db->escape($transaction_data['debug_data']) . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function updateTransaction($transaction) {
+ $this->db->query("UPDATE " . DB_PREFIX . "paypal_order_transaction SET paypal_order_id = " . (int)$transaction['paypal_order_id'] . ", transaction_id = '" . $this->db->escape($transaction['transaction_id']) . "', parent_id = '" . $this->db->escape($transaction['parent_id']) . "', date_added = '" . $this->db->escape($transaction['date_added']) . "', note = '" . $this->db->escape($transaction['note']) . "', msgsubid = '" . $this->db->escape($transaction['msgsubid']) . "', receipt_id = '" . $this->db->escape($transaction['receipt_id']) . "', payment_type = '" . $this->db->escape($transaction['payment_type']) . "', payment_status = '" . $this->db->escape($transaction['payment_status']) . "', pending_reason = '" . $this->db->escape($transaction['pending_reason']) . "', transaction_entity = '" . $this->db->escape($transaction['transaction_entity']) . "', amount = '" . $this->db->escape($transaction['amount']) . "', debug_data = '" . $this->db->escape($transaction['debug_data']) . "', call_data = '" . $this->db->escape($transaction['call_data']) . "' WHERE paypal_order_transaction_id = '" . (int)$transaction['paypal_order_transaction_id'] . "'");
+ }
+
+ public function getPaypalOrderByTransactionId($transaction_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'");
+
+ return $query->rows;
+ }
+
+ public function getFailedTransaction($paypal_order_transaction_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE paypal_order_transaction_id = '" . (int)$paypal_order_transaction_id . "'");
+
+ return $query->row;
+ }
+
+ public function getLocalTransaction($transaction_id) {
+ $result = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTransaction($transaction_id) {
+ $call_data = array(
+ 'METHOD' => 'GetTransactionDetails',
+ 'TRANSACTIONID' => $transaction_id,
+ );
+
+ return $this->call($call_data);
+ }
+
+ public function getCurrencies() {
+ return array(
+ 'AUD',
+ 'BRL',
+ 'CAD',
+ 'CZK',
+ 'DKK',
+ 'EUR',
+ 'HKD',
+ 'HUF',
+ 'ILS',
+ 'JPY',
+ 'MYR',
+ 'MXN',
+ 'NOK',
+ 'NZD',
+ 'PHP',
+ 'PLN',
+ 'GBP',
+ 'SGD',
+ 'SEK',
+ 'CHF',
+ 'TWD',
+ 'THB',
+ 'TRY',
+ 'USD',
+ );
+ }
+
+ public function getOrderId($transaction_id) {
+ $query = $this->db->query("SELECT `o`.`order_id` FROM `" . DB_PREFIX . "paypal_order_transaction` `ot` LEFT JOIN `" . DB_PREFIX . "paypal_order` `o` ON `o`.`paypal_order_id` = `ot`.`paypal_order_id` WHERE `ot`.`transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+
+ return $query->row['order_id'];
+ }
+
+ public function getCapturedTotal($paypal_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $query->row['amount'];
+ }
+
+ public function getRefundedTotal($paypal_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `payment_status` = 'Refunded' AND `parent_id` != ''");
+
+ return $query->row['amount'];
+ }
+
+ public function getRefundedTotalByParentId($transaction_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `parent_id` = '" . $this->db->escape($transaction_id) . "' AND `payment_type` = 'refund'");
+
+ return $query->row['amount'];
+ }
+
+ public function cleanReturn($data) {
+ $data = explode('&', $data);
+
+ $arr = array();
+
+ foreach ($data as $k => $v) {
+ $tmp = explode('=', $v);
+ $arr[$tmp[0]] = urldecode($tmp[1]);
+ }
+
+ return $arr;
+ }
+
+ public function log($data, $title = null) {
+ if ($this->config->get('payment_pp_express_debug')) {
+ $this->log->write('PayPal Express debug (' . $title . '): ' . json_encode($data));
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['paypal_order_id']);
+ $order['captured'] = $this->totalCaptured($order['paypal_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function totalCaptured($paypal_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTransactions($paypal_order_id) {
+ $query = $this->db->query("SELECT `ot`.*, (SELECT COUNT(`ot2`.`paypal_order_id`) FROM `" . DB_PREFIX . "paypal_order_transaction` `ot2` WHERE `ot2`.`parent_id` = `ot`.`transaction_id`) AS `children` FROM `" . DB_PREFIX . "paypal_order_transaction` `ot` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' ORDER BY `date_added` ASC");
+
+ return $query->rows;
+ }
+
+ public function getTokens($test) {
+ if ($test == 'sandbox') {
+ $endpoint = 'https://api.sandbox.paypal.com/v1/oauth2/token';
+ $client_id = 'Ad3QTBAHwhuNI_blejO4_RqvES74yWRUC61c5QVNDbxkq9csbLpDZogWp_0n';
+ $client_secret = 'EGqgGxCqjs1GIa5l1Ex_Flq0Mb2oMT3rJu2kwz6FuF9QKyxCg6qNqyddxCCW';
+ } else {
+ $endpoint = 'https://api.paypal.com/v1/oauth2/token';
+ $client_id = 'AWyAiBCUYsE156N8YpiiISQpSpep2HPoXXPrf33VBeYleE0SQJg40pgEqZvq';
+ $client_secret = 'EEkc6xB30fDkgUO_YldWWHxKDquY7LBRId6FJ-parAR1CsVpK35zB6U0SIh4';
+ }
+
+ $request = '';
+ $request .= 'client_id=' . $client_id;
+ $request .= '&client_secret=' . $client_secret;
+ $request .= '&grant_type=client_credentials';
+
+ $additional_opts = array(
+ CURLOPT_USERPWD => $client_id . ':' . $client_secret,
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => $request
+ );
+
+ $curl = $this->curl($endpoint, $additional_opts);
+
+ $this->log('cURL Response 1: ' . print_r($curl, 1));
+
+ return $curl;
+ }
+
+ public function getUserInfo($merchant_id, $test, $access_token) {
+ if ($test == 'sandbox') {
+ $endpoint = 'https://api.sandbox.paypal.com/v1/customer/partners/T4E8WSXT43QPJ/merchant-integrations';
+ } else {
+ $endpoint = 'https://api.paypal.com/v1/customer/partners/9PDNYE4RZBVFJ/merchant-integrations';
+ }
+
+ $endpoint1 = $endpoint . '?tracking_id=' . $merchant_id;
+
+ $header = array();
+ $header[] = 'Content-Type: application/json';
+ $header[] = 'Authorization: Bearer ' . $access_token;
+ $header[] = 'PAYPAL_SERVICE_VERSION:1.2.0';
+
+ $additional_opts = array(
+ CURLOPT_HTTPHEADER => $header,
+ );
+
+ $curl = $this->curl($endpoint1, $additional_opts);
+
+ $this->log('cURL Response 2: ' . print_r($curl, 1));
+
+ if (isset($curl->merchant_id)) {
+ $endpoint2 = $endpoint . '/' . $curl->merchant_id;
+ $curl2 = $this->curl($endpoint2, $additional_opts);
+
+ $this->log('cURL Response 3: ' . print_r($curl2, 1));
+
+ if (isset($curl2->api_credentials->signature)) {
+ return $curl2->api_credentials->signature;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+
+ public function call($data) {
+ if ($this->config->get('payment_pp_express_test') == 1) {
+ $api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
+ $user = $this->config->get('payment_pp_express_sandbox_username');
+ $password = $this->config->get('payment_pp_express_sandbox_password');
+ $signature = $this->config->get('payment_pp_express_sandbox_signature');
+ } else {
+ $api_endpoint = 'https://api-3t.paypal.com/nvp';
+ $user = $this->config->get('payment_pp_express_username');
+ $password = $this->config->get('payment_pp_express_password');
+ $signature = $this->config->get('payment_pp_express_signature');
+ }
+
+ $settings = array(
+ 'USER' => $user,
+ 'PWD' => $password,
+ 'SIGNATURE' => $signature,
+ 'VERSION' => '84',
+ 'BUTTONSOURCE' => 'OpenCart_Cart_EC',
+ );
+
+ $this->log($data, 'Call data');
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $api_endpoint,
+ CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&")
+ );
+
+ $ch = curl_init();
+
+ curl_setopt_array($ch, $defaults);
+
+ if (!$result = curl_exec($ch)) {
+ $log_data = array(
+ 'curl_error' => curl_error($ch),
+ 'curl_errno' => curl_errno($ch)
+ );
+
+ $this->log($log_data, 'CURL failed');
+ return false;
+ }
+
+ $this->log($result, 'Result');
+
+ curl_close($ch);
+
+ return $this->cleanReturn($result);
+ }
+
+ private function curl($endpoint, $additional_opts = array()) {
+ $default_opts = array(
+ CURLOPT_PORT => 443,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_URL => $endpoint,
+ );
+
+ $ch = curl_init($endpoint);
+
+ $opts = $default_opts + $additional_opts;
+
+ curl_setopt_array($ch, $opts);
+
+ $response = json_decode(curl_exec($ch));
+
+ curl_close($ch);
+
+ return $response;
+ }
+}
diff --git a/public/admin/model/extension/payment/pp_payflow_iframe.php b/public/admin/model/extension/payment/pp_payflow_iframe.php
new file mode 100644
index 0000000..34c2251
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_payflow_iframe.php
@@ -0,0 +1,136 @@
+<?php
+class ModelExtensionPaymentPPPayflowIFrame extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "paypal_payflow_iframe_order` (
+ `order_id` int(11) DEFAULT NULL,
+ `secure_token_id` varchar(255) NOT NULL,
+ `transaction_reference` varchar(255) DEFAULT NULL,
+ `transaction_type` varchar(1) DEFAULT NULL,
+ `complete` tinyint(4) NOT NULL DEFAULT '0',
+ PRIMARY KEY(`order_id`),
+ KEY `secure_token_id` (`secure_token_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "paypal_payflow_iframe_order_transaction` (
+ `order_id` int(11) NOT NULL,
+ `transaction_reference` varchar(255) NOT NULL,
+ `transaction_type` char(1) NOT NULL,
+ `time` datetime NOT NULL,
+ `amount` decimal(10,4) DEFAULT NULL,
+ PRIMARY KEY (`transaction_reference`),
+ KEY `order_id` (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_payflow_iframe_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_payflow_iframe_order_transaction`;");
+ }
+
+ public function log($message) {
+ if ($this->config->get('payment_pp_payflow_iframe_debug')) {
+ $log = new Log('payflow-iframe.log');
+ $log->write($message);
+ }
+ }
+
+ public function getOrder($order_id) {
+ $result = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_payflow_iframe_order WHERE order_id = " . (int)$order_id);
+
+ if ($result->num_rows) {
+ $order = $result->row;
+ } else {
+ $order = false;
+ }
+
+ return $order;
+ }
+
+ public function updateOrderStatus($order_id, $status) {
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_payflow_iframe_order
+ SET `complete` = " . (int)$status . "
+ WHERE order_id = '" . (int)$order_id . "'
+ ");
+ }
+
+ public function addTransaction($data) {
+ $this->db->query("
+ INSERT INTO " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ SET order_id = " . (int)$data['order_id'] . ",
+ transaction_reference = '" . $this->db->escape($data['transaction_reference']) . "',
+ transaction_type = '" . $this->db->escape($data['type']) . "',
+ `time` = NOW(),
+ `amount` = '" . $this->db->escape($data['amount']) . "'
+ ");
+ }
+
+ public function getTransactions($order_id) {
+ return $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ WHERE order_id = " . (int)$order_id . "
+ ORDER BY `time` ASC")->rows;
+ }
+
+ public function getTransaction($transaction_reference) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ WHERE transaction_reference = '" . $this->db->escape($transaction_reference) . "'")->row;
+
+ if ($result) {
+ $transaction = $result;
+ } else {
+ $transaction = false;
+ }
+
+ return $transaction;
+ }
+
+ public function call($data) {
+ $default_parameters = array(
+ 'USER' => $this->config->get('payment_pp_payflow_iframe_user'),
+ 'VENDOR' => $this->config->get('payment_pp_payflow_iframe_vendor'),
+ 'PWD' => $this->config->get('payment_pp_payflow_iframe_password'),
+ 'PARTNER' => $this->config->get('payment_pp_payflow_iframe_partner'),
+ 'BUTTONSOURCE' => 'OpenCart_Cart_PFP',
+ );
+
+ $call_parameters = array_merge($data, $default_parameters);
+
+ if ($this->config->get('payment_pp_payflow_iframe_test')) {
+ $url = 'https://pilot-payflowpro.paypal.com';
+ } else {
+ $url = 'https://payflowpro.paypal.com';
+ }
+
+ $query_params = array();
+
+ foreach ($call_parameters as $key => $value) {
+ $query_params[] = $key . '=' . utf8_decode($value);
+ }
+
+ $this->log('Call data: ' . implode('&', $query_params));
+
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, implode('&', $query_params));
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HEADER, false);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 30);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+
+ $response = curl_exec($curl);
+
+ $this->log('Response data: ' . $response);
+
+ $response_params = array();
+ parse_str($response, $response_params);
+
+ return $response_params;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pp_pro_iframe.php b/public/admin/model/extension/payment/pp_pro_iframe.php
new file mode 100644
index 0000000..f1df3b5
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_pro_iframe.php
@@ -0,0 +1,261 @@
+<?php
+class ModelExtensionPaymentPPProIframe extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_iframe_order` (
+ `paypal_iframe_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` ENUM('Complete','NotComplete') DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authorization_id` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`paypal_iframe_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_iframe_order_transaction` (
+ `paypal_iframe_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `paypal_iframe_order_id` int(11) NOT NULL,
+ `transaction_id` CHAR(20) NOT NULL,
+ `parent_id` CHAR(20) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `note` VARCHAR(255) NOT NULL,
+ `msgsubid` CHAR(38) NOT NULL,
+ `receipt_id` CHAR(20) NOT NULL,
+ `payment_type` ENUM('none','echeck','instant', 'refund', 'void') DEFAULT NULL,
+ `payment_status` CHAR(20) NOT NULL,
+ `pending_reason` CHAR(50) NOT NULL,
+ `transaction_entity` CHAR(50) NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `debug_data` TEXT NOT NULL,
+ `call_data` TEXT NOT NULL,
+ PRIMARY KEY (`paypal_iframe_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_iframe_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_iframe_order`;");
+ }
+
+ private function getTransactions($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT `ot`.*, ( SELECT count(`ot2`.`paypal_iframe_order_id`) FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot2` WHERE `ot2`.`parent_id` = `ot`.`transaction_id` ) AS `children` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTotalCaptured($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTotalRefunded($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "' AND `payment_status` = 'Refunded'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTotalRefundedTransaction($transaction_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `parent_id` = '" . $this->db->escape($transaction_id) . "' AND `payment_type` = 'refund'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_iframe_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['paypal_iframe_order_id']);
+ $order['captured'] = $this->getTotalCaptured($order['paypal_iframe_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function call($data) {
+
+ if ($this->config->get('payment_pp_pro_iframe_test') == 1) {
+ $api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
+ } else {
+ $api_endpoint = 'https://api-3t.paypal.com/nvp';
+ }
+
+ $settings = array(
+ 'USER' => $this->config->get('payment_pp_pro_iframe_user'),
+ 'PWD' => $this->config->get('payment_pp_pro_iframe_password'),
+ 'SIGNATURE' => $this->config->get('payment_pp_pro_iframe_sig'),
+ 'VERSION' => '84',
+ 'BUTTONSOURCE' => 'WM_PRO_OPENCART_UK_' . VERSION,
+ );
+
+ $this->log($data, 'Call data');
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $api_endpoint,
+ CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&")
+ );
+
+ $ch = curl_init();
+
+ curl_setopt_array($ch, $defaults);
+
+ if (!$result = curl_exec($ch)) {
+
+ $log_data = array(
+ 'curl_error' => curl_error($ch),
+ 'curl_errno' => curl_errno($ch)
+ );
+
+ $this->log($log_data, 'CURL failed');
+
+ return false;
+ }
+
+ $this->log($result, 'Result');
+
+ curl_close($ch);
+
+ return $this->cleanReturn($result);
+ }
+
+ public function updateOrder($capture_status, $order_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_iframe_order` SET `date_modified` = now(), `capture_status` = '" . $this->db->escape($capture_status) . "' WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function updateTransaction($transaction) {
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_iframe_order_transaction
+ SET paypal_iframe_order_id = " . (int)$transaction['paypal_iframe_order_id'] . ",
+ transaction_id = '" . $this->db->escape($transaction['transaction_id']) . "',
+ parent_id = '" . $this->db->escape($transaction['parent_id']) . "',
+ date_added = '" . $this->db->escape($transaction['date_added']) . "',
+ note = '" . $this->db->escape($transaction['note']) . "',
+ msgsubid = '" . $this->db->escape($transaction['msgsubid']) . "',
+ receipt_id = '" . $this->db->escape($transaction['receipt_id']) . "',
+ payment_type = '" . $this->db->escape($transaction['payment_type']) . "',
+ payment_status = '" . $this->db->escape($transaction['payment_status']) . "',
+ pending_reason = '" . $this->db->escape($transaction['pending_reason']) . "',
+ transaction_entity = '" . $this->db->escape($transaction['transaction_entity']) . "',
+ amount = '" . $this->db->escape($transaction['amount']) . "',
+ debug_data = '" . $this->db->escape($transaction['debug_data']) . "',
+ call_data = '" . $this->db->escape($transaction['call_data']) . "'
+ WHERE paypal_iframe_order_transaction_id = " . (int)$transaction['paypal_iframe_order_transaction_id'] . "
+ ");
+ }
+
+ public function addTransaction($transaction_data, $request_data = array()) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_iframe_order_transaction` SET `paypal_iframe_order_id` = '" . (int)$transaction_data['paypal_iframe_order_id'] . "', `transaction_id` = '" . $this->db->escape($transaction_data['transaction_id']) . "', `parent_id` = '" . $this->db->escape($transaction_data['parent_id']) . "', `date_added` = NOW(), `note` = '" . $this->db->escape($transaction_data['note']) . "', `msgsubid` = '" . $this->db->escape($transaction_data['msgsubid']) . "', `receipt_id` = '" . $this->db->escape($transaction_data['receipt_id']) . "', `payment_type` = '" . $this->db->escape($transaction_data['payment_type']) . "', `payment_status` = '" . $this->db->escape($transaction_data['payment_status']) . "', `pending_reason` = '" . $this->db->escape($transaction_data['pending_reason']) . "', `transaction_entity` = '" . $this->db->escape($transaction_data['transaction_entity']) . "', `amount` = '" . (float)$transaction_data['amount'] . "', `debug_data` = '" . $this->db->escape($transaction_data['debug_data']) . "'");
+
+ $paypal_iframe_order_transaction_id = $this->db->getLastId();
+
+ if ($request_data) {
+ $serialized_data = json_encode($request_data);
+
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_iframe_order_transaction
+ SET call_data = '" . $this->db->escape($serialized_data) . "'
+ WHERE paypal_iframe_order_transaction_id = " . (int)$paypal_iframe_order_transaction_id . "
+ LIMIT 1
+ ");
+ }
+
+ return $paypal_iframe_order_transaction_id;
+ }
+
+ public function log($data, $title = null) {
+ if ($this->config->get('payment_pp_pro_iframe_debug')) {
+ $log = new Log('pp_pro_iframe.log');
+ $log->write($title . ': ' . json_encode($data));
+ }
+ }
+
+ public function getTransaction($transaction_id) {
+ $call_data = array(
+ 'METHOD' => 'GetTransactionDetails',
+ 'TRANSACTIONID' => $transaction_id,
+ );
+
+ return $this->call($call_data);
+ }
+
+ public function getOrderId($transaction_id) {
+ $qry = $this->db->query("SELECT `o`.`order_id` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot` LEFT JOIN `" . DB_PREFIX . "paypal_iframe_order` `o` ON `o`.`paypal_iframe_order_id` = `ot`.`paypal_iframe_order_id` WHERE `ot`.`transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ return $qry->row['order_id'];
+ } else {
+ return false;
+ }
+ }
+
+ public function updateAuthorizationId($paypal_iframe_order_id, $authorization_id) {
+ $this->db->query("
+ UPDATE `" . DB_PREFIX . "paypal_iframe_order`
+ SET `authorization_id` = '" . $this->db->escape($authorization_id) . "'
+ WHERE `paypal_iframe_order_id` = '" . $this->db->escape($paypal_iframe_order_id) . "'
+ ");
+ }
+
+ public function updateRefundTransaction($transaction_id, $transaction_type) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_iframe_order_transaction` SET `payment_status` = '" . $this->db->escape($transaction_type) . "' WHERE `transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+ }
+
+ public function getFailedTransaction($paypl_iframe_order_transaction_id) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_iframe_order_transaction
+ WHERE paypal_iframe_order_transaction_id = " . (int)$paypl_iframe_order_transaction_id . "
+ ")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function getLocalTransaction($transaction_id) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_iframe_order_transaction
+ WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'
+ ")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ protected function cleanReturn($data) {
+ $data = explode('&', $data);
+
+ $arr = array();
+
+ foreach ($data as $k => $v) {
+ $tmp = explode('=', $v);
+ $arr[$tmp[0]] = urldecode($tmp[1]);
+ }
+
+ return $arr;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/realex.php b/public/admin/model/extension/payment/realex.php
new file mode 100644
index 0000000..d2b7a7a
--- /dev/null
+++ b/public/admin/model/extension/payment/realex.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentRealex extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_order` (
+ `realex_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_order_transaction` (
+ `realex_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `realex_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `void_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `capture_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function updateForRebate($realex_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $realex_order['order_ref'];
+
+ if (empty($realex_order['pasref_previous'])) {
+ $pas_ref = $realex_order['pasref'];
+ } else {
+ $pas_ref = $realex_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $realex_order['order_ref'];
+ $pas_ref = $realex_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebate_hash = sha1($this->config->get('payment_realex_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebate_hash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `rebate_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['realex_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($realex_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($realex_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "realex_order_transaction` SET `realex_order_id` = '" . (int)$realex_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_realex_debug') == 1) {
+ $log = new Log('realex.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/realex_remote.php b/public/admin/model/extension/payment/realex_remote.php
new file mode 100644
index 0000000..be40791
--- /dev/null
+++ b/public/admin/model/extension/payment/realex_remote.php
@@ -0,0 +1,260 @@
+<?php
+class ModelExtensionPaymentRealexRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_remote_order` (
+ `realex_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_remote_order_transaction` (
+ `realex_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `realex_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function updateForRebate($realex_remote_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $realex_order['order_ref'];
+
+ if (empty($realex_order['pasref_previous'])) {
+ $pas_ref = $realex_order['pasref'];
+ } else {
+ $pas_ref = $realex_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $realex_order['order_ref'];
+ $pas_ref = $realex_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebatehash = sha1($this->config->get('payment_realex_remote_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebatehash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `rebate_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['realex_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($realex_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($realex_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "realex_remote_order_transaction` SET `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_realex_remote_debug') == 1) {
+ $log = new Log('realex_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/sagepay_direct.php b/public/admin/model/extension/payment/sagepay_direct.php
new file mode 100644
index 0000000..370e4f0
--- /dev/null
+++ b/public/admin/model/extension/payment/sagepay_direct.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentSagepayDirect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order` (
+ `sagepay_direct_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ `card_id` INT(11),
+ PRIMARY KEY (`sagepay_direct_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order_transaction` (
+ `sagepay_direct_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `sagepay_direct_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_direct_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order_recurring` (
+ `sagepay_direct_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_direct_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_card`;");
+ }
+
+ public function void($order_id) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['release_status'] == 0) {
+
+ $void_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorVoidTx';
+ $void_data['VPSProtocol'] = '2.23';
+ }
+
+ $void_data['TxType'] = 'VOID';
+ $void_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $void_data['VendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $void_data['VPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $void_data['SecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $void_data['TxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `void_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($sagepay_direct_order['sagepay_direct_order_id']);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['release_status'] == 0 && ($total_released + $amount <= $sagepay_direct_order['total'])) {
+ $release_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorReleaseTx';
+ $release_data['VPSProtocol'] = '2.23';
+ }
+
+ $release_data['TxType'] = 'RELEASE';
+ $release_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $release_data['VendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $release_data['VPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $release_data['SecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $release_data['TxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+ $release_data['Amount'] = $amount;
+
+ $response_data = $this->sendCurl($url, $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `release_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['rebate_status'] != 1) {
+
+ $refund_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorRefundTx';
+ $refund_data['VPSProtocol'] = '2.23';
+ }
+
+ $refund_data['TxType'] = 'REFUND';
+ $refund_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $refund_data['VendorTxCode'] = $sagepay_direct_order['sagepay_direct_order_id'] . rand();
+ $refund_data['Amount'] = $amount;
+ $refund_data['Currency'] = $sagepay_direct_order['currency_code'];
+ $refund_data['Description'] = substr($this->config->get('config_name'), 0, 100);
+ $refund_data['RelatedVPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $refund_data['RelatedVendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $refund_data['RelatedSecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $refund_data['RelatedTxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $refund_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `rebate_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_direct_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['sagepay_direct_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($sagepay_direct_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($sagepay_direct_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "sagepay_direct_order_transaction` SET `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($sagepay_direct_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($sagepay_direct_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $payment_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($payment_data));
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ $response_info = explode(chr(10), $response);
+
+ foreach ($response_info as $string) {
+ if (strpos($string, '=') && isset($i)) {
+ $parts = explode('=', $string, 2);
+ $data['RepeatResponseData_' . $i][trim($parts[0])] = trim($parts[1]);
+ } elseif (strpos($string, '=')) {
+ $parts = explode('=', $string, 2);
+ $data[trim($parts[0])] = trim($parts[1]);
+ }
+ }
+ return $data;
+ }
+
+ public function logger($title, $data) {
+ if ($this->config->get('payment_sagepay_direct_debug')) {
+ $log = new Log('sagepay_direct.log');
+ $log->write($title . ': ' . print_r($data, 1));
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/sagepay_server.php b/public/admin/model/extension/payment/sagepay_server.php
new file mode 100644
index 0000000..8dacbd9
--- /dev/null
+++ b/public/admin/model/extension/payment/sagepay_server.php
@@ -0,0 +1,266 @@
+<?php
+class ModelExtensionPaymentSagepayServer extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order` (
+ `sagepay_server_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `customer_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order_transaction` (
+ `sagepay_server_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `sagepay_server_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order_recurring` (
+ `sagepay_server_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_card`;");
+ }
+
+ public function void($order_id) {
+ $sagepay_server_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['release_status'] == 0) {
+
+ $void_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorVoidTx';
+ $void_data['VPSProtocol'] = '2.23';
+ }
+
+ $void_data['TxType'] = 'VOID';
+ $void_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $void_data['VendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $void_data['VPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $void_data['SecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $void_data['TxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($sagepay_server_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `void_status` = '" . (int)$status . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $sagepay_server_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($sagepay_server_order['sagepay_server_order_id']);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['release_status'] == 0 && ($total_released + $amount <= $sagepay_server_order['total'])) {
+ $release_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorReleaseTx';
+ $release_data['VPSProtocol'] = '2.23';
+ }
+
+ $release_data['TxType'] = 'RELEASE';
+ $release_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $release_data['VendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $release_data['VPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $release_data['SecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $release_data['TxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+ $release_data['Amount'] = $amount;
+
+ $response_data = $this->sendCurl($url, $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($sagepay_server_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `release_status` = '" . (int)$status . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+ }
+
+ public function updateForRebate($sagepay_server_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $sagepay_server_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['rebate_status'] != 1) {
+
+ $refund_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorRefundTx';
+ $refund_data['VPSProtocol'] = '2.23';
+ }
+
+ $refund_data['TxType'] = 'REFUND';
+ $refund_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $refund_data['VendorTxCode'] = $sagepay_server_order['sagepay_server_order_id'] . rand();
+ $refund_data['Amount'] = $amount;
+ $refund_data['Currency'] = $sagepay_server_order['currency_code'];
+ $refund_data['Description'] = substr($this->config->get('config_name'), 0, 100);
+ $refund_data['RelatedVPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $refund_data['RelatedVendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $refund_data['RelatedSecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $refund_data['RelatedTxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $refund_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_server_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['sagepay_server_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($sagepay_server_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($sagepay_server_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "sagepay_server_order_transaction` SET `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($sagepay_server_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($sagepay_server_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $payment_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($payment_data));
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ $response_info = explode(chr(10), $response);
+
+ foreach ($response_info as $string) {
+ if (strpos($string, '=') && isset($i)) {
+ $parts = explode('=', $string, 2);
+ $data['RepeatResponseData_' . $i][trim($parts[0])] = trim($parts[1]);
+ } elseif (strpos($string, '=')) {
+ $parts = explode('=', $string, 2);
+ $data[trim($parts[0])] = trim($parts[1]);
+ }
+ }
+ return $data;
+ }
+
+ public function logger($title, $data) {
+ if ($this->config->get('payment_sagepay_server_debug')) {
+ $log = new Log('sagepay_server.log');
+ $log->write($title . ': ' . print_r($data, 1));
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/securetrading_pp.php b/public/admin/model/extension/payment/securetrading_pp.php
new file mode 100644
index 0000000..2e21b3a
--- /dev/null
+++ b/public/admin/model/extension/payment/securetrading_pp.php
@@ -0,0 +1,208 @@
+<?php
+class ModelExtensionPaymentSecureTradingPp extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order` (
+ `securetrading_pp_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_reference` varchar(127) DEFAULT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_pp_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction` (
+ `securetrading_pp_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `securetrading_pp_order_id` INT(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'reversed') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_pp_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "securetrading_pp_order");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction`;");
+ }
+
+ public function void($order_id) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
+
+ $request_node->addChild('updates')->addChild('settlement')->addChild('settlestatus', 3);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($securetrading_pp_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `void_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($securetrading_pp_order['securetrading_pp_order_id']);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0 && $total_released <= $amount) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
+
+ $settlement_node = $request_node->addChild('updates')->addChild('settlement');
+ $settlement_node->addChild('settlestatus', 0);
+ $settlement_node->addChild('settlemainamount', $amount)->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($securetrading_pp_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `release_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+ }
+
+ public function updateForRebate($securetrading_pp_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $refunded_amount) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['rebate_status'] != 1) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'REFUND');
+
+ $request_node->addChild('merchant')->addChild('orderreference', $order_id);
+
+ $operation_node = $request_node->addChild('operation');
+ $operation_node->addChild('accounttypedescription', 'ECOM');
+ $operation_node->addChild('parenttransactionreference', $securetrading_pp_order['transaction_reference']);
+ $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+
+ $billing_node = $request_node->addChild('billing');
+ $billing_node->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
+ $billing_node->addChild('amount', str_replace('.', '', $refunded_amount));
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['securetrading_pp_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($securetrading_pp_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($securetrading_pp_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "securetrading_pp_order_transaction` SET `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "', `created` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($securetrading_pp_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRebated($securetrading_pp_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function increaseRefundedAmount($order_id, $amount) {
+ $this->db->query("UPDATE " . DB_PREFIX . "securetrading_pp_order SET refunded = refunded + " . (double)$amount . " WHERE order_id = " . (int)$order_id);
+ }
+
+ public function call($data) {
+ $ch = curl_init();
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://webservices.securetrading.net/xml/',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading PP',
+ 'Content-Length: ' . strlen($data),
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_pp_webservice_username') . ':' . $this->config->get('payment_securetrading_pp_webservice_password')),
+ ),
+ CURLOPT_POSTFIELDS => $data,
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading PP CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ public function logger($message) {
+ $log = new Log('securetrading_pp.log');
+ $log->write($message);
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/securetrading_ws.php b/public/admin/model/extension/payment/securetrading_ws.php
new file mode 100644
index 0000000..5b2b567
--- /dev/null
+++ b/public/admin/model/extension/payment/securetrading_ws.php
@@ -0,0 +1,351 @@
+<?php
+class ModelExtensionPaymentSecureTradingWs extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_ws_order` (
+ `securetrading_ws_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `md` varchar(1024) DEFAULT NULL,
+ `transaction_reference` varchar(127) DEFAULT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_ws_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_ws_order_transaction` (
+ `securetrading_ws_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `securetrading_ws_order_id` INT(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'reversed') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_ws_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "securetrading_ws_order");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "securetrading_ws_order_transaction`;");
+ }
+
+ public function void($order_id) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['release_status'] == 0) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_ws_order['transaction_reference']);
+
+ $request_node->addChild('updates')->addChild('settlement')->addChild('settlestatus', 3);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($securetrading_ws_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `void_status` = '" . (int)$status . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($securetrading_ws_order['securetrading_ws_order_id']);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['release_status'] == 0 && $total_released <= $amount) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_ws_order['transaction_reference']);
+
+ $settlement_node = $request_node->addChild('updates')->addChild('settlement');
+ $settlement_node->addChild('settlestatus', 0);
+ $settlement_node->addChild('settlemainamount', $amount)->addAttribute('currencycode', $securetrading_ws_order['currency_code']);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($securetrading_ws_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `release_status` = '" . (int)$status . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+ }
+
+ public function updateForRebate($securetrading_ws_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $refunded_amount) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['rebate_status'] != 1) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'REFUND');
+
+ $request_node->addChild('merchant')->addChild('orderreference', $order_id);
+
+ $operation_node = $request_node->addChild('operation');
+ $operation_node->addChild('accounttypedescription', 'ECOM');
+ $operation_node->addChild('parenttransactionreference', $securetrading_ws_order['transaction_reference']);
+ $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+
+ $billing_node = $request_node->addChild('billing');
+ $billing_node->addAttribute('currencycode', $securetrading_ws_order['currency_code']);
+ $billing_node->addChild('amount', str_replace('.', '', $refunded_amount));
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_ws_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['securetrading_ws_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($securetrading_ws_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($securetrading_ws_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "securetrading_ws_order_transaction` SET `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "', `created` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($securetrading_ws_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRebated($securetrading_ws_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function increaseRefundedAmount($order_id, $amount) {
+ $this->db->query("UPDATE " . DB_PREFIX . "securetrading_ws_order SET refunded = refunded + " . (double)$amount . " WHERE order_id = " . (int)$order_id);
+ }
+
+ public function getCsv($data) {
+ $ch = curl_init();
+
+ $post_data = array();
+ $post_data['sitereferences'] = $this->config->get('payment_securetrading_ws_site_reference');
+ $post_data['startdate'] = $data['date_from'];
+ $post_data['enddate'] = $data['date_to'];
+ $post_data['accounttypedescriptions'] = 'ECOM';
+
+ if ($data['detail']) {
+ $post_data['optionalfields'] = array(
+ 'parenttransactionreference',
+ 'accounttypedescription',
+ 'requesttypedescription',
+ 'mainamount',
+ 'currencyiso3a',
+ 'errorcode',
+ 'authcode',
+ 'customerip',
+ 'fraudrating',
+ 'orderreference',
+ 'paymenttypedescription',
+ 'maskedpan',
+ 'expirydate',
+ 'settlestatus',
+ 'settlemainamount',
+ 'settleduedate',
+ 'securityresponsesecuritycode',
+ 'securityresponseaddress',
+ 'securityresponsepostcode',
+ 'billingprefixname',
+ 'billingfirstname',
+ 'billingmiddlename',
+ 'billinglastname',
+ 'billingpremise',
+ 'billingstreet',
+ 'billingtown',
+ 'billingcounty',
+ 'billingemail',
+ 'billingcountryiso2a',
+ 'billingpostcode',
+ 'billingtelephones',
+ 'customerprefixname',
+ 'customerfirstname',
+ 'customermiddlename',
+ 'customerlastname',
+ 'customerpremise',
+ 'customerstreet',
+ 'customertown',
+ 'customercounty',
+ 'customeremail',
+ 'customercountryiso2a',
+ 'customerpostcode',
+ 'customertelephones',
+ );
+ } else {
+ $post_data['optionalfields'] = array(
+ 'orderreference',
+ 'currencyiso3a',
+ 'errorcode',
+ 'paymenttypedescription',
+ 'settlestatus',
+ 'requesttypedescription',
+ 'mainamount',
+ 'billingfirstname',
+ 'billinglastname',
+ );
+ }
+
+ if (isset($data['currency']) && !empty($data['currency'])) {
+ $post_data['currencyiso3as'] = $data['currency'];
+ }
+
+ if (isset($data['status']) && !empty($data['status'])) {
+ $post_data['errorcodes'] = $data['status'];
+ }
+
+ if (isset($data['payment_type']) && !empty($data['payment_type'])) {
+ $post_data['paymenttypedescriptions'] = $data['payment_type'];
+ }
+
+ if (isset($data['request']) && !empty($data['request'])) {
+ $post_data['requesttypedescriptions'] = $data['request'];
+ }
+
+ if (isset($data['settle_status']) && !empty($data['settle_status'])) {
+ $post_data['settlestatuss'] = $data['settle_status'];
+ }
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://myst.securetrading.net/auto/transactions/transactionsearch',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading WS',
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_ws_csv_username') . ':' . $this->config->get('payment_securetrading_ws_csv_password')),
+ ),
+ CURLOPT_POSTFIELDS => $this->encodePost($post_data),
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading WS CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ if (empty($response) || $response === 'No records found for search') {
+ return false;
+ }
+
+ if (preg_match('/401 Authorization Required/', $response)) {
+ return false;
+ }
+
+ return $response;
+ }
+
+ private function encodePost($data) {
+ $params = array();
+
+ foreach ($data as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $v) {
+ $params[] = $key . '=' . rawurlencode($v);
+ }
+ } else {
+ $params[] = $key . '=' . rawurlencode($value);
+ }
+ }
+
+ return implode('&', $params);
+ }
+
+ public function call($data) {
+ $ch = curl_init();
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://webservices.securetrading.net/xml/',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading WS',
+ 'Content-Length: ' . strlen($data),
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_ws_username') . ':' . $this->config->get('payment_securetrading_ws_password')),
+ ),
+ CURLOPT_POSTFIELDS => $data,
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading WS CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ public function logger($message) {
+ $log = new Log('securetrading_ws.log');
+ $log->write($message);
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/squareup.php b/public/admin/model/extension/payment/squareup.php
new file mode 100644
index 0000000..d5c428c
--- /dev/null
+++ b/public/admin/model/extension/payment/squareup.php
@@ -0,0 +1,117 @@
+<?php
+
+class ModelExtensionPaymentSquareup extends Model {
+ const RECURRING_ACTIVE = 1;
+ const RECURRING_INACTIVE = 2;
+ const RECURRING_CANCELLED = 3;
+ const RECURRING_SUSPENDED = 4;
+ const RECURRING_EXPIRED = 5;
+ const RECURRING_PENDING = 6;
+
+ public function getTransaction($squareup_transaction_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "squareup_transaction` WHERE squareup_transaction_id='" . (int)$squareup_transaction_id . "'")->row;
+ }
+
+ public function getTransactions($data) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "squareup_transaction`";
+
+ if (isset($data['order_id'])) {
+ $sql .= " WHERE order_id='" . (int)$data['order_id'] . "'";
+ }
+
+ $sql .= " ORDER BY created_at DESC";
+
+ if (isset($data['start']) && isset($data['limit'])) {
+ $sql .= " LIMIT " . $data['start'] . ', ' . $data['limit'];
+ }
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function getTotalTransactions($data) {
+ $sql = "SELECT COUNT(*) as total FROM `" . DB_PREFIX . "squareup_transaction`";
+
+ if (isset($data['order_id'])) {
+ $sql .= " WHERE order_id='" . (int)$data['order_id'] . "'";
+ }
+
+ return $this->db->query($sql)->row['total'];
+ }
+
+ public function updateTransaction($squareup_transaction_id, $type, $refunds = array()) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "squareup_transaction` SET transaction_type='" . $this->db->escape($type) . "', is_refunded='" . (int)!empty($refunds) . "', refunds='" . $this->db->escape(json_encode($refunds)) . "' WHERE squareup_transaction_id='" . (int)$squareup_transaction_id . "'");
+ }
+
+ public function getOrderStatusId($order_id, $transaction_status = null) {
+ if ($transaction_status) {
+ return $this->config->get('payment_squareup_status_' . strtolower($transaction_status));
+ } else {
+ $this->load->model('sale/order');
+
+ $order_info = $this->model_sale_order->getOrder($order_id);
+
+ return $order_info['order_status_id'];
+ }
+ }
+
+ public function editOrderRecurringStatus($order_recurring_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = '" . (int)$status . "' WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'");
+ }
+
+ public function createTables() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_transaction` (
+ `squareup_transaction_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `transaction_id` char(40) NOT NULL,
+ `merchant_id` char(32) NOT NULL,
+ `location_id` varchar(32) NOT NULL,
+ `order_id` int(11) NOT NULL,
+ `transaction_type` char(20) NOT NULL,
+ `transaction_amount` decimal(15,2) NOT NULL,
+ `transaction_currency` char(3) NOT NULL,
+ `billing_address_city` char(100) NOT NULL,
+ `billing_address_company` char(100) NOT NULL,
+ `billing_address_country` char(3) NOT NULL,
+ `billing_address_postcode` char(10) NOT NULL,
+ `billing_address_province` char(20) NOT NULL,
+ `billing_address_street_1` char(100) NOT NULL,
+ `billing_address_street_2` char(100) NOT NULL,
+ `device_browser` char(255) NOT NULL,
+ `device_ip` char(15) NOT NULL,
+ `created_at` char(29) NOT NULL,
+ `is_refunded` tinyint(1) NOT NULL,
+ `refunded_at` varchar(29) NOT NULL,
+ `tenders` text NOT NULL,
+ `refunds` text NOT NULL,
+ PRIMARY KEY (`squareup_transaction_id`),
+ KEY `order_id` (`order_id`),
+ KEY `transaction_id` (`transaction_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_token` (
+ `squareup_token_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `customer_id` int(11) NOT NULL,
+ `sandbox` tinyint(1) NOT NULL,
+ `token` char(40) NOT NULL,
+ `date_added` datetime NOT NULL,
+ `brand` VARCHAR(32) NOT NULL,
+ `ends_in` VARCHAR(4) NOT NULL,
+ PRIMARY KEY (`squareup_token_id`),
+ KEY `getCards` (`customer_id`, `sandbox`),
+ KEY `verifyCardCustomer` (`squareup_token_id`, `customer_id`),
+ KEY `cardExists` (`customer_id`, `brand`, `ends_in`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_customer` (
+ `customer_id` int(11) NOT NULL,
+ `sandbox` tinyint(1) NOT NULL,
+ `square_customer_id` varchar(32) NOT NULL,
+ PRIMARY KEY (`customer_id`, `sandbox`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+ }
+
+ public function dropTables() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_transaction`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_token`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_customer`");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/worldpay.php b/public/admin/model/extension/payment/worldpay.php
new file mode 100644
index 0000000..ae2d9ce
--- /dev/null
+++ b/public/admin/model/extension/payment/worldpay.php
@@ -0,0 +1,175 @@
+<?php
+
+class ModelExtensionPaymentWorldpay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order` (
+ `worldpay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_code` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order_transaction` (
+ `worldpay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `worldpay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('payment', 'refund') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order_recurring` (
+ `worldpay_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `order_code` VARCHAR(50),
+ `token` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(22) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_card`;");
+ }
+
+ public function refund($order_id, $amount) {
+ $worldpay_order = $this->getOrder($order_id);
+
+ if (!empty($worldpay_order) && $worldpay_order['refund_status'] != 1) {
+ $order['refundAmount'] = (int)($amount * 100);
+
+ $url = $worldpay_order['order_code'] . '/refund';
+
+ $response_data = $this->sendCurl($url, $order);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($worldpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "worldpay_order` SET `refund_status` = '" . (int)$status . "' WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "worldpay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['worldpay_order_id'], $qry->row['currency_code']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($worldpay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "'");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, false);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($worldpay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "worldpay_order_transaction` SET `worldpay_order_id` = '" . (int)$worldpay_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($worldpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($worldpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function sendCurl($url, $order) {
+
+ $json = json_encode($order);
+
+ $curl = curl_init();
+
+ curl_setopt($curl, CURLOPT_URL, 'https://api.worldpay.com/v1/orders/' . $url);
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
+ curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 10);
+ curl_setopt(
+ $curl, CURLOPT_HTTPHEADER, array(
+ "Authorization: " . $this->config->get('payment_worldpay_service_key'),
+ "Content-Type: application/json",
+ "Content-Length: " . strlen($json)
+ )
+ );
+
+ $result = json_decode(curl_exec($curl));
+ curl_close($curl);
+
+ $response = array();
+
+ if (isset($result)) {
+ $response['status'] = $result->httpStatusCode;
+ $response['message'] = $result->message;
+ $response['full_details'] = $result;
+ } else {
+ $response['status'] = 'success';
+ }
+
+ return $response;
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_worldpay_debug') == 1) {
+ $log = new Log('worldpay.log');
+ $log->write($message);
+ }
+ }
+
+}