1<?php 2class ControllerExtensionPaymentSecureTradingWs extends Controller { 3 public function index() { 4 $this->load->model('checkout/order'); 5 $this->load->language('extension/payment/securetrading_ws'); 6 7 if(!isset($this->session->data['order_id'])) { 8 return false; 9 } 10 11 $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); 12 13 if ($order_info) { 14 $data['entry_type'] = $this->language->get('entry_type'); 15 $data['entry_number'] = $this->language->get('entry_number'); 16 $data['entry_expire_date'] = $this->language->get('entry_expire_date'); 17 $data['entry_cvv2'] = $this->language->get('entry_cvv2'); 18 19 $data['text_card_details'] = $this->language->get('text_card_details'); 20 $data['text_wait'] = $this->language->get('text_wait'); 21 22 $data['button_confirm'] = $this->language->get('button_confirm'); 23 24 $cards = array( 25 'AMEX' => 'American Express', 26 'VISA' => 'Visa', 27 'DELTA' => 'Visa Debit', 28 'ELECTRON' => 'Visa Electron', 29 'PURCHASING' => 'Visa Purchasing', 30 'VPAY' => 'V Pay', 31 'MASTERCARD' => 'MasterCard', 32 'MASTERCARDDEBIT' => 'MasterCard Debit', 33 'MAESTRO' => 'Maestro', 34 'PAYPAL' => 'PayPal', 35 ); 36 37 for ($i = 1; $i <= 12; $i++) { 38 $data['months'][] = array( 39 'text' => strftime('%B', mktime(0, 0, 0, $i, 1, 2000)), 40 'value' => sprintf('%02d', $i) 41 ); 42 } 43 44 $today = getdate(); 45 46 $data['year_expire'] = array(); 47 48 for ($i = $today['year']; $i < $today['year'] + 11; $i++) { 49 $data['year_expire'][] = array( 50 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), 51 'value' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)) 52 ); 53 } 54 55 $data['cards'] = array(); 56 57 foreach ($this->config->get('payment_securetrading_ws_cards_accepted') as $card_type) { 58 $data['cards'][$card_type] = $cards[$card_type]; 59 } 60 61 return $this->load->view('extension/payment/securetrading_ws', $data); 62 } 63 } 64 65 public function process() { 66 $this->load->model('checkout/order'); 67 $this->load->model('localisation/country'); 68 $this->load->model('extension/payment/securetrading_ws'); 69 $this->load->language('extension/payment/securetrading_ws'); 70 71 if(!isset($this->session->data['order_id'])) { 72 return false; 73 } 74 75 $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); 76 77 if ($order_info) { 78 if ($this->config->get('payment_securetrading_ws_3d_secure')) { 79 $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>'); 80 $requestblock_xml->addAttribute('version', '3.67'); 81 $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username')); 82 83 $request_node = $requestblock_xml->addChild('request'); 84 $request_node->addAttribute('type', 'THREEDQUERY'); 85 86 $merchant_node = $request_node->addChild('merchant'); 87 $merchant_node->addChild('orderreference', $order_info['order_id']); 88 $merchant_node->addChild('termurl', $this->url->link('extension/payment/securetrading_ws/threedreturn', '', true)); 89 90 $settlement_node = $request_node->addChild('settlement'); 91 $settlement_date = date('Y-m-d', strtotime(date('Y-m-d') . ' +' . $this->config->get('payment_securetrading_ws_settle_due_date') . ' days')); 92 $settlement_node->addChild('settleduedate', $settlement_date); 93 $settlement_node->addChild('settlestatus', $this->config->get('payment_securetrading_ws_settle_status')); 94 95 $customer_node = $request_node->addChild('customer'); 96 $customer_node->addChild('useragent', $order_info['user_agent']); 97 $customer_node->addChild('accept', $this->request->server['HTTP_ACCEPT']); 98 99 $billing_node = $request_node->addChild('billing'); 100 $amount_node = $billing_node->addChild('amount', str_replace('.', '', $this->model_extension_payment_securetrading_ws->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value']))); 101 $amount_node->addAttribute('currencycode', $order_info['currency_code']); 102 103 $billing_node->addChild('premise', $order_info['payment_address_1']); 104 $billing_node->addChild('postcode', $order_info['payment_postcode']); 105 106 $name_node = $billing_node->addChild('name'); 107 $name_node->addChild('first', $order_info['payment_firstname']); 108 $name_node->addChild('last', $order_info['payment_lastname']); 109 110 $payment_node = $billing_node->addChild('payment'); 111 $payment_node->addAttribute('type', $this->request->post['type']); 112 $payment_node->addChild('pan', $this->request->post['number']); 113 $payment_node->addChild('expirydate', $this->request->post['expire_month'] . '/' . $this->request->post['expire_year']); 114 $payment_node->addChild('securitycode', $this->request->post['cvv2']); 115 116 $operation_node = $request_node->addChild('operation'); 117 $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference')); 118 $operation_node->addChild('accounttypedescription', 'ECOM'); 119 120 $response = $this->model_extension_payment_securetrading_ws->call($requestblock_xml->asXML()); 121 122 if ($response !== false) { 123 $response_xml = simplexml_load_string($response); 124 125 if ($response_xml->response['type'] == 'THREEDQUERY') { 126 $error_code = (int)$response_xml->response->error->code; 127 128 if ($error_code == 0) { 129 $enrolled = (string)$response_xml->response->threedsecure->enrolled; 130 131 if ($enrolled == 'Y') { 132 $acs_url = (string)$response_xml->response->threedsecure->acsurl; 133 $md = (string)$response_xml->response->threedsecure->md; 134 $pareq = (string)$response_xml->response->threedsecure->pareq; 135 136 $this->model_extension_payment_securetrading_ws->addMd($order_info['order_id'], $md); 137 138 $json['status'] = 1; 139 $json['acs_url'] = $acs_url; 140 $json['md'] = $md; 141 $json['pareq'] = $pareq; 142 $json['term_url'] = $this->url->link('extension/payment/securetrading_ws/threedreturn', '', true); 143 } else { 144 $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>'); 145 $requestblock_xml->addAttribute('version', '3.67'); 146 $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username')); 147 148 $request_node = $requestblock_xml->addChild('request'); 149 $request_node->addAttribute('type', 'AUTH'); 150 151 $request_node->addChild('merchant')->addChild('orderreference', $order_info['order_id']); 152 153 $operation_node = $request_node->addChild('operation'); 154 $operation_node->addChild('parenttransactionreference', (string)$response_xml->response->transactionreference); 155 $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference')); 156 157 $response = $this->model_extension_payment_securetrading_ws->call($requestblock_xml->asXML()); 158 159 $json = $this->processAuthResponse($response, $order_info['order_id']); 160 } 161 } else { 162 $json['message'] = $this->language->get('text_transaction_declined'); 163 $json['status'] = 0; 164 } 165 } else { 166 $json['message'] = $this->language->get('text_transaction_failed'); 167 $json['status'] = 0; 168 } 169 } else { 170 $json['message'] = $this->language->get('text_connection_error'); 171 $json['status'] = 0; 172 } 173 } else { 174 $country = $this->model_localisation_country->getCountry($order_info['payment_country_id']); 175 176 $json = array(); 177 178 $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>'); 179 $requestblock_xml->addAttribute('version', '3.67'); 180 $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username')); 181 182 $request_node = $requestblock_xml->addChild('request'); 183 $request_node->addAttribute('type', 'AUTH'); 184 $operation_node = $request_node->addChild('operation'); 185 $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference')); 186 $operation_node->addChild('accounttypedescription', 'ECOM'); 187 188 $merchant_node = $request_node->addChild('merchant'); 189 $merchant_node->addChild('orderreference', $order_info['order_id']); 190 191 $settlement_node = $request_node->addChild('settlement'); 192 $settlement_date = date('Y-m-d', strtotime(date('Y-m-d') . ' +' . $this->config->get('payment_securetrading_ws_settle_due_date') . ' days')); 193 $settlement_node->addChild('settleduedate', $settlement_date); 194 $settlement_node->addChild('settlestatus', $this->config->get('payment_securetrading_ws_settle_status')); 195 196 $billing_node = $request_node->addChild('billing'); 197 $billing_node->addChild('premise', $order_info['payment_address_1']); 198 $billing_node->addChild('street', $order_info['payment_address_2']); 199 $billing_node->addChild('town', $order_info['payment_city']); 200 $billing_node->addChild('county', $order_info['payment_zone']); 201 $billing_node->addChild('country', $country['iso_code_2']); 202 $billing_node->addChild('postcode', $order_info['payment_postcode']); 203 $billing_node->addChild('email', $order_info['email']); 204 $name_node = $billing_node->addChild('name'); 205 206 $name_node->addChild('first', $order_info['payment_firstname']); 207 $name_node->addChild('last', $order_info['payment_lastname']); 208 209 $amount_node = $billing_node->addChild('amount', str_replace('.', '', $this->model_extension_payment_securetrading_ws->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value']))); 210 $amount_node->addAttribute('currencycode', $order_info['currency_code']); 211 212 $payment_node = $billing_node->addChild('payment'); 213 $payment_node->addAttribute('type', $this->request->post['type']); 214 $payment_node->addChild('pan', $this->request->post['number']); 215 $payment_node->addChild('expirydate', $this->request->post['expire_month'] . '/' . $this->request->post['expire_year']); 216 $payment_node->addChild('securitycode', $this->request->post['cvv2']); 217 218 $response = $this->model_extension_payment_securetrading_ws->call($requestblock_xml->asXML()); 219 220 $json = $this->processAuthResponse($response, $order_info['order_id']); 221 } 222 $this->response->setOutput(json_encode($json)); 223 } 224 } 225 226 public function threedreturn() { 227 $this->load->model('checkout/order'); 228 $this->load->model('extension/payment/securetrading_ws'); 229 $this->load->language('extension/payment/securetrading_ws'); 230 231 // Using unmodified $_POST to access values as per Secure Trading's requirements 232 if (isset($_POST['PaRes']) && !empty($_POST['PaRes']) && isset($_POST['MD']) && !empty($_POST['MD'])) { 233 $md = $_POST['MD']; 234 $pares = $_POST['PaRes']; 235 236 $order_id = $this->model_extension_payment_securetrading_ws->getOrderId($md); 237 238 if ($order_id) { 239 $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>'); 240 $requestblock_xml->addAttribute('version', '3.67'); 241 $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username')); 242 243 $request_node = $requestblock_xml->addChild('request'); 244 $request_node->addAttribute('type', 'AUTH'); 245 246 $request_node->addChild('merchant')->addChild('orderreference', $order_id); 247 248 $operation_node = $request_node->addChild('operation'); 249 $operation_node->addChild('md', $md); 250 $operation_node->addChild('pares', $pares); 251 252 $response = $this->model_extension_payment_securetrading_ws->call($requestblock_xml->asXML()); 253 254 if ($response) { 255 $response_xml = simplexml_load_string($response); 256 257 $error_code = (int)$response_xml->response->error->code; 258 259 if ($error_code == 0) { 260 $postcode_status = (int)$response_xml->response->security->postcode; 261 $security_code_status = (int)$response_xml->response->security->securitycode; 262 $address_status = (int)$response_xml->response->security->address; 263 $authcode = (string)$response_xml->response->authcode; 264 $threed_status = (string)$response_xml->response->threedsecure->status; 265 266 $status_code_mapping = array( 267 0 => $this->language->get('text_not_given'), 268 1 => $this->language->get('text_not_checked'), 269 2 => $this->language->get('text_match'), 270 4 => $this->language->get('text_not_match'), 271 ); 272 273 $threed_status_mapping = array( 274 'Y' => $this->language->get('text_authenticated'), 275 'N' => $this->language->get('text_not_authenticated'), 276 'A' => $this->language->get('text_authentication_not_completed'), 277 'U' => $this->language->get('text_unable_to_perform'), 278 ); 279 280 $message = sprintf($this->language->get('text_auth_code'), $authcode) . "\n"; 281 $message .= sprintf($this->language->get('text_postcode_check'), $status_code_mapping[$postcode_status]) . "\n"; 282 $message .= sprintf($this->language->get('text_security_code_check'), $status_code_mapping[$security_code_status]) . "\n"; 283 $message .= sprintf($this->language->get('text_address_check'), $status_code_mapping[$address_status]) . "\n"; 284 $message .= sprintf($this->language->get('text_3d_secure_check'), $threed_status_mapping[$threed_status]) . "\n"; 285 286 $transaction_reference = (string)$response_xml->response->transactionreference; 287 $this->model_extension_payment_securetrading_ws->updateReference($order_id, $transaction_reference); 288 289 $this->model_extension_payment_securetrading_ws->confirmOrder($order_id, $this->config->get('payment_securetrading_ws_order_status_id')); 290 $this->model_extension_payment_securetrading_ws->updateOrder($order_id, $this->config->get('payment_securetrading_ws_order_status_id'), $message); 291 292 $this->response->redirect($this->url->link('checkout/success', '', true)); 293 } else { 294 $this->model_extension_payment_securetrading_ws->updateOrder($order_id, $this->config->get('payment_securetrading_ws_declined_order_status_id')); 295 296 $this->session->data['error'] = $this->language->get('text_transaction_declined'); 297 $this->response->redirect($this->url->link('checkout/checkout', '', true)); 298 } 299 } else { 300 $this->session->data['error'] = $this->language->get('error_failure'); 301 $this->response->redirect($this->url->link('checkout/checkout', '', true)); 302 } 303 } else { 304 $this->session->data['error'] = $this->language->get('error_failure'); 305 $this->response->redirect($this->url->link('checkout/checkout', '', true)); 306 } 307 } else { 308 $this->session->data['error'] = $this->language->get('error_failure'); 309 $this->response->redirect($this->url->link('checkout/checkout', '', true)); 310 } 311 } 312 313 private function processAuthResponse($response, $order_id) { 314 $json = array(); 315 316 if ($response !== false) { 317 $response_xml = simplexml_load_string($response); 318 319 if ($response_xml->response['type'] == 'AUTH') { 320 $error_code = (int)$response_xml->response->error->code; 321 322 if ($error_code == 0) { 323 $postcode_status = (int)$response_xml->response->security->postcode; 324 $security_code_status = (int)$response_xml->response->security->securitycode; 325 $address_status = (int)$response_xml->response->security->address; 326 $authcode = (string)$response_xml->response->authcode; 327 328 $status_code_mapping = array( 329 0 => $this->language->get('text_not_given'), 330 1 => $this->language->get('text_not_checked'), 331 2 => $this->language->get('text_match'), 332 4 => $this->language->get('text_not_match'), 333 ); 334 335 $message = sprintf($this->language->get('text_auth_code'), $authcode) . "\n"; 336 $message .= sprintf($this->language->get('text_postcode_check'), $status_code_mapping[$postcode_status]) . "\n"; 337 $message .= sprintf($this->language->get('text_security_code_check'), $status_code_mapping[$security_code_status]) . "\n"; 338 $message .= sprintf($this->language->get('text_address_check'), $status_code_mapping[$address_status]) . "\n"; 339 340 $transaction_reference = (string)$response_xml->response->transactionreference; 341 $this->model_extension_payment_securetrading_ws->updateReference($order_id, $transaction_reference); 342 343 $this->model_extension_payment_securetrading_ws->confirmOrder($order_id, $this->config->get('payment_securetrading_ws_order_status_id')); 344 $this->model_extension_payment_securetrading_ws->updateOrder($order_id, $this->config->get('payment_securetrading_ws_order_status_id'), $message); 345 346 $json['redirect'] = $this->url->link('checkout/success'); 347 $json['status'] = 1; 348 } else { 349 $this->model_extension_payment_securetrading_ws->updateOrder($order_id, $this->config->get('payment_securetrading_ws_declined_order_status_id')); 350 351 $json['message'] = $this->language->get('text_transaction_declined'); 352 $json['status'] = 0; 353 } 354 } else { 355 $this->model_extension_payment_securetrading_ws->updateOrder($order_id, $this->config->get('payment_securetrading_ws_failed_order_status_id')); 356 357 $json['message'] = $this->language->get('text_transaction_failed'); 358 $json['status'] = 0; 359 } 360 } else { 361 $json['message'] = $this->language->get('text_connection_error'); 362 $json['status'] = 0; 363 } 364 365 return $json; 366 } 367} 368