diff options
Diffstat (limited to 'public/admin/model/extension/payment')
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); + } + } + +} |