cardinity.php (9610B)
1 <?php 2 class ControllerExtensionPaymentCardinity extends Controller { 3 public function index() { 4 $this->load->language('extension/payment/cardinity'); 5 6 $data['months'] = array(); 7 8 for ($i = 1; $i <= 12; $i++) { 9 $data['months'][] = array( 10 'text' => strftime('%B', mktime(0, 0, 0, $i, 1, 2000)), 11 'value' => sprintf('%02d', $i) 12 ); 13 } 14 15 $today = getdate(); 16 17 $data['years'] = array(); 18 19 for ($i = $today['year']; $i < $today['year'] + 11; $i++) { 20 $data['years'][] = array( 21 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), 22 'value' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)) 23 ); 24 } 25 26 return $this->load->view('extension/payment/cardinity', $data); 27 } 28 29 public function send() { 30 $this->load->model('checkout/order'); 31 $this->load->model('extension/payment/cardinity'); 32 33 $this->load->language('extension/payment/cardinity'); 34 35 $json = array(); 36 37 $json['error'] = $json['success'] = $json['3ds'] = ''; 38 39 $payment = false; 40 41 $error = $this->validate(); 42 43 if (!$error) { 44 $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); 45 46 if (strlen($order_info['order_id']) < 2) { 47 $order_id = '0' . $order_info['order_id']; 48 } else { 49 $order_id = $order_info['order_id']; 50 } 51 52 if (!empty($order_info['payment_iso_code_2'])) { 53 $order_country = $order_info['payment_iso_code_2']; 54 } else { 55 $order_country = $order_info['shipping_iso_code_2']; 56 } 57 58 $payment_data = array( 59 'amount' => (float)$this->currency->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value'], false), 60 'currency' => $order_info['currency_code'], 61 'order_id' => $order_id, 62 'country' => $order_country, 63 'payment_method' => 'card', 64 'payment_instrument' => array( 65 'pan' => preg_replace('!\s+!', '', $this->request->post['pan']), 66 'exp_year' => (int)$this->request->post['exp_year'], 67 'exp_month' => (int)$this->request->post['exp_month'], 68 'cvc' => $this->request->post['cvc'], 69 'holder' => $this->request->post['holder'] 70 ), 71 ); 72 73 try { 74 $payment = $this->model_extension_payment_cardinity->createPayment($this->config->get('payment_cardinity_key'), $this->config->get('payment_cardinity_secret'), $payment_data); 75 } catch (Cardinity\Exception\Declined $exception) { 76 $this->failedOrder($this->language->get('error_payment_declined'), $this->language->get('error_payment_declined')); 77 78 $json['redirect'] = $this->url->link('checkout/checkout', '', true); 79 } catch (Exception $exception) { 80 $this->failedOrder(); 81 82 $json['redirect'] = $this->url->link('checkout/checkout', '', true); 83 } 84 85 $successful_order_statuses = array( 86 'approved', 87 'pending' 88 ); 89 90 if ($payment) { 91 if (!in_array($payment->getStatus(), $successful_order_statuses)) { 92 $this->failedOrder($payment->getStatus()); 93 94 $json['redirect'] = $this->url->link('checkout/checkout', '', true); 95 } else { 96 $this->model_extension_payment_cardinity->addOrder(array( 97 'order_id' => $this->session->data['order_id'], 98 'payment_id' => $payment->getId() 99 )); 100 101 if ($payment->getStatus() == 'pending') { 102 //3ds 103 $authorization_information = $payment->getAuthorizationInformation(); 104 105 $encryption_data = array( 106 'order_id' => $this->session->data['order_id'], 107 'secret' => $this->config->get('payment_cardinity_secret') 108 ); 109 110 $hash = $this->encryption->encrypt($this->config->get('config_encryption'), json_encode($encryption_data)); 111 112 $json['3ds'] = array( 113 'url' => $authorization_information->getUrl(), 114 'PaReq' => $authorization_information->getData(), 115 'TermUrl' => $this->url->link('extension/payment/cardinity/threeDSecureCallback', '', true), 116 'hash' => $hash 117 ); 118 } elseif ($payment->getStatus() == 'approved') { 119 $this->finalizeOrder($payment); 120 121 $json['redirect'] = $this->url->link('checkout/success', '', true); 122 } 123 } 124 } 125 } else { 126 $json['error'] = $error; 127 } 128 129 $this->response->addHeader('Content-Type: application/json'); 130 $this->response->setOutput(json_encode($json)); 131 } 132 133 public function threeDSecureForm() { 134 $this->load->model('extension/payment/cardinity'); 135 136 $this->load->language('extension/payment/cardinity'); 137 138 $success = false; 139 $redirect = false; 140 141 $encryption_data = array( 142 'order_id' => $this->session->data['order_id'], 143 'secret' => $this->config->get('payment_cardinity_secret') 144 ); 145 146 $hash = $this->encryption->encrypt($this->config->get('config_encryption'), json_encode($encryption_data)); 147 148 if (hash_equals($hash, $this->request->post['hash'])) { 149 $success = true; 150 151 $data['url'] = $this->request->post['url']; 152 $data['PaReq'] = $this->request->post['PaReq']; 153 $data['TermUrl'] = $this->request->post['TermUrl']; 154 $data['MD'] = $hash; 155 } else { 156 $this->failedOrder($this->language->get('error_invalid_hash')); 157 158 $redirect = $this->url->link('checkout/checkout', '', true); 159 } 160 161 $data['success'] = $success; 162 $data['redirect'] = $redirect; 163 164 $this->response->setOutput($this->load->view('extension/payment/cardinity_3ds', $data)); 165 } 166 167 public function threeDSecureCallback() { 168 $this->load->model('extension/payment/cardinity'); 169 170 $this->load->language('extension/payment/cardinity'); 171 172 $success = false; 173 174 $error = ''; 175 176 $encryption_data = array( 177 'order_id' => $this->session->data['order_id'], 178 'secret' => $this->config->get('payment_cardinity_secret') 179 ); 180 181 $hash = $this->encryption->encrypt($this->config->get('config_encryption'), json_encode($encryption_data)); 182 183 if (hash_equals($hash, $this->request->post['MD'])) { 184 $order = $this->model_extension_payment_cardinity->getOrder($encryption_data['order_id']); 185 186 if ($order && $order['payment_id']) { 187 $payment = $this->model_extension_payment_cardinity->finalizePayment($this->config->get('payment_cardinity_key'), $this->config->get('payment_cardinity_secret'), $order['payment_id'], $this->request->post['PaRes']); 188 189 if ($payment && $payment->getStatus() == 'approved') { 190 $success = true; 191 } else { 192 $error = $this->language->get('error_finalizing_payment'); 193 } 194 } else { 195 $error = $this->language->get('error_unknown_order_id'); 196 } 197 } else { 198 $error = $this->language->get('error_invalid_hash'); 199 } 200 201 if ($success) { 202 $this->finalizeOrder($payment); 203 204 $this->response->redirect($this->url->link('checkout/success', '', true)); 205 } else { 206 $this->failedOrder($error); 207 208 $this->response->redirect($this->url->link('checkout/checkout', '', true)); 209 } 210 } 211 212 private function finalizeOrder($payment) { 213 $this->load->model('checkout/order'); 214 215 $this->load->language('extension/payment/cardinity'); 216 217 $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('payment_cardinity_order_status_id')); 218 219 $this->model_extension_payment_cardinity->log($this->language->get('text_payment_success')); 220 $this->model_extension_payment_cardinity->log($payment); 221 } 222 223 private function failedOrder($log = null, $alert = null) { 224 $this->load->language('extension/payment/cardinity'); 225 226 $this->model_extension_payment_cardinity->log($this->language->get('text_payment_failed')); 227 228 if ($log) { 229 $this->model_extension_payment_cardinity->log($log); 230 } 231 232 if ($alert) { 233 $this->session->data['error'] = $alert; 234 } else { 235 $this->session->data['error'] = $this->language->get('error_process_order'); 236 } 237 } 238 239 private function validate() { 240 $this->load->model('checkout/order'); 241 $this->load->model('extension/payment/cardinity'); 242 243 $error = array(); 244 245 if (!$this->session->data['order_id']) { 246 $error['warning'] = $this->language->get('error_process_order'); 247 } 248 249 if (!$error) { 250 $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); 251 252 if (!$order_info) { 253 $error['warning'] = $this->language->get('error_process_order'); 254 } 255 } 256 257 if (!in_array($order_info['currency_code'], $this->model_extension_payment_cardinity->getSupportedCurrencies())) { 258 $error['warning'] = $this->language->get('error_invalid_currency'); 259 } 260 261 if (!isset($this->request->post['holder']) || utf8_strlen($this->request->post['holder']) < 1 || utf8_strlen($this->request->post['holder']) > 32) { 262 $error['holder'] = true; 263 } 264 265 if (!isset($this->request->post['pan']) || utf8_strlen($this->request->post['pan']) < 1 || utf8_strlen($this->request->post['pan']) > 19) { 266 $error['pan'] = true; 267 } 268 269 if (!isset($this->request->post['pan']) || !is_numeric(preg_replace('!\s+!', '', $this->request->post['pan']))) { 270 $error['pan'] = true; 271 } 272 273 if (!isset($this->request->post['exp_month']) || !isset($this->request->post['exp_year'])) { 274 $error['expiry_date'] = true; 275 } else { 276 $expiry = new DateTime(); 277 $expiry->setDate($this->request->post['exp_year'], $this->request->post['exp_month'], '1'); 278 $expiry->modify('+1 month'); 279 $expiry->modify('-1 day'); 280 281 $now = new DateTime(); 282 283 if ($expiry < $now) { 284 $error['expiry_date'] = true; 285 } 286 } 287 288 if (!isset($this->request->post['cvc']) || utf8_strlen($this->request->post['cvc']) < 1 || utf8_strlen($this->request->post['cvc']) > 4) { 289 $error['cvc'] = true; 290 } 291 292 return $error; 293 } 294 }