1<?php
2class ModelExtensionPaymentSecureTradingPp extends Model {
3	public function install() {
4		$this->db->query("
5			CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order` (
6			  `securetrading_pp_order_id` INT(11) NOT NULL AUTO_INCREMENT,
7			  `order_id` INT(11) NOT NULL,
8			  `transaction_reference` varchar(127) DEFAULT NULL,
9			  `created` DATETIME NOT NULL,
10			  `modified` DATETIME NOT NULL,
11			  `release_status` INT(1) DEFAULT NULL,
12			  `void_status` INT(1) DEFAULT NULL,
13			  `settle_type` INT(1) DEFAULT NULL,
14			  `rebate_status` INT(1) DEFAULT NULL,
15			  `currency_code` CHAR(3) NOT NULL,
16			  `total` DECIMAL( 10, 2 ) NOT NULL,
17			  PRIMARY KEY (`securetrading_pp_order_id`)
18			) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
19
20		$this->db->query("
21			CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction` (
22			  `securetrading_pp_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
23			  `securetrading_pp_order_id` INT(11) NOT NULL,
24			  `created` DATETIME NOT NULL,
25			  `type` ENUM('auth', 'payment', 'rebate', 'reversed') DEFAULT NULL,
26			  `amount` DECIMAL( 10, 2 ) NOT NULL,
27			  PRIMARY KEY (`securetrading_pp_order_transaction_id`)
28			) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
29	}
30
31	public function uninstall() {
32		$this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "securetrading_pp_order");
33		$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction`;");
34	}
35
36	public function void($order_id) {
37		$securetrading_pp_order = $this->getOrder($order_id);
38
39		if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0) {
40
41			$requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
42			$requestblock_xml->addAttribute('version', '3.67');
43			$requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
44
45			$request_node = $requestblock_xml->addChild('request');
46			$request_node->addAttribute('type', 'TRANSACTIONUPDATE');
47
48			$filter_node = $request_node->addChild('filter');
49			$filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
50			$filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
51
52			$request_node->addChild('updates')->addChild('settlement')->addChild('settlestatus', 3);
53
54			return $this->call($requestblock_xml->asXML());
55		} else {
56			return false;
57		}
58	}
59
60	public function updateVoidStatus($securetrading_pp_order_id, $status) {
61		$this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `void_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
62	}
63
64	public function release($order_id, $amount) {
65		$securetrading_pp_order = $this->getOrder($order_id);
66		$total_released = $this->getTotalReleased($securetrading_pp_order['securetrading_pp_order_id']);
67
68		if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0 && $total_released <= $amount) {
69
70			$requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
71			$requestblock_xml->addAttribute('version', '3.67');
72			$requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
73
74			$request_node = $requestblock_xml->addChild('request');
75			$request_node->addAttribute('type', 'TRANSACTIONUPDATE');
76
77			$filter_node = $request_node->addChild('filter');
78			$filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
79			$filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
80
81			$settlement_node = $request_node->addChild('updates')->addChild('settlement');
82			$settlement_node->addChild('settlestatus', 0);
83			$settlement_node->addChild('settlemainamount', $amount)->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
84
85			return $this->call($requestblock_xml->asXML());
86		} else {
87			return false;
88		}
89	}
90
91	public function updateReleaseStatus($securetrading_pp_order_id, $status) {
92		$this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `release_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
93	}
94
95	public function updateForRebate($securetrading_pp_order_id, $order_ref) {
96		$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");
97	}
98
99	public function rebate($order_id, $refunded_amount) {
100		$securetrading_pp_order = $this->getOrder($order_id);
101
102		if (!empty($securetrading_pp_order) && $securetrading_pp_order['rebate_status'] != 1) {
103
104			$requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
105			$requestblock_xml->addAttribute('version', '3.67');
106			$requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
107
108			$request_node = $requestblock_xml->addChild('request');
109			$request_node->addAttribute('type', 'REFUND');
110
111			$request_node->addChild('merchant')->addChild('orderreference', $order_id);
112
113			$operation_node = $request_node->addChild('operation');
114			$operation_node->addChild('accounttypedescription', 'ECOM');
115			$operation_node->addChild('parenttransactionreference', $securetrading_pp_order['transaction_reference']);
116			$operation_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
117
118			$billing_node = $request_node->addChild('billing');
119			$billing_node->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
120			$billing_node->addChild('amount', str_replace('.', '', $refunded_amount));
121
122			return $this->call($requestblock_xml->asXML());
123		} else {
124			return false;
125		}
126	}
127
128	public function getOrder($order_id) {
129		$qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
130
131		if ($qry->num_rows) {
132			$order = $qry->row;
133			$order['transactions'] = $this->getTransactions($order['securetrading_pp_order_id']);
134
135			return $order;
136		} else {
137			return false;
138		}
139	}
140
141	private function getTransactions($securetrading_pp_order_id) {
142		$qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
143
144		if ($qry->num_rows) {
145			return $qry->rows;
146		} else {
147			return false;
148		}
149	}
150
151	public function addTransaction($securetrading_pp_order_id, $type, $total) {
152		$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 . "'");
153	}
154
155	public function getTotalReleased($securetrading_pp_order_id) {
156		$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')");
157
158		return (double)$query->row['total'];
159	}
160
161	public function getTotalRebated($securetrading_pp_order_id) {
162		$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'");
163
164		return (double)$query->row['total'];
165	}
166
167	public function increaseRefundedAmount($order_id, $amount) {
168		$this->db->query("UPDATE " . DB_PREFIX . "securetrading_pp_order SET refunded = refunded + " . (double)$amount . " WHERE order_id = " . (int)$order_id);
169	}
170
171	public function call($data) {
172		$ch = curl_init();
173
174		$defaults = array(
175			CURLOPT_POST => 1,
176			CURLOPT_HEADER => 0,
177			CURLOPT_SSL_VERIFYPEER => 0,
178			CURLOPT_URL => 'https://webservices.securetrading.net/xml/',
179			CURLOPT_FRESH_CONNECT => 1,
180			CURLOPT_RETURNTRANSFER => 1,
181			CURLOPT_FORBID_REUSE => 1,
182			CURLOPT_TIMEOUT => 15,
183			CURLOPT_HTTPHEADER => array(
184				'User-Agent: OpenCart - Secure Trading PP',
185				'Content-Length: ' . strlen($data),
186				'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_pp_webservice_username') . ':' . $this->config->get('payment_securetrading_pp_webservice_password')),
187			),
188			CURLOPT_POSTFIELDS => $data,
189		);
190
191		curl_setopt_array($ch, $defaults);
192
193		$response = curl_exec($ch);
194
195		if ($response === false) {
196			$this->log->write('Secure Trading PP CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
197		}
198
199		curl_close($ch);
200
201		return $response;
202	}
203
204	public function logger($message) {
205		$log = new Log('securetrading_pp.log');
206		$log->write($message);
207	}
208}