pp_express.php (13922B)
1 <?php 2 class ModelExtensionPaymentPPExpress extends Model { 3 public function getMethod($address, $total) { 4 $this->load->language('extension/payment/pp_express'); 5 6 $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_pp_express_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); 7 8 if ($this->config->get('payment_pp_express_total') > $total) { 9 $status = false; 10 } elseif (!$this->config->get('payment_pp_express_geo_zone_id')) { 11 $status = true; 12 } elseif ($query->num_rows) { 13 $status = true; 14 } else { 15 $status = false; 16 } 17 18 $method_data = array(); 19 20 if ($status) { 21 $method_data = array( 22 'code' => 'pp_express', 23 'title' => $this->language->get('text_title'), 24 'terms' => '', 25 'sort_order' => $this->config->get('payment_pp_express_sort_order') 26 ); 27 } 28 29 return $method_data; 30 } 31 32 public function addOrder($order_data) { 33 /** 34 * 1 to 1 relationship with order table (extends order info) 35 */ 36 37 $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_order` SET 38 `order_id` = '" . (int)$order_data['order_id'] . "', 39 `date_added` = NOW(), 40 `date_modified` = NOW(), 41 `capture_status` = '" . $this->db->escape($order_data['capture_status']) . "', 42 `currency_code` = '" . $this->db->escape($order_data['currency_code']) . "', 43 `total` = '" . (float)$order_data['total'] . "', 44 `authorization_id` = '" . $this->db->escape($order_data['authorization_id']) . "'"); 45 46 return $this->db->getLastId(); 47 } 48 49 public function addTransaction($transaction_data) { 50 /** 51 * 1 to many relationship with paypal order table, many transactions per 1 order 52 */ 53 54 $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_order_transaction` SET 55 `paypal_order_id` = '" . (int)$transaction_data['paypal_order_id'] . "', 56 `transaction_id` = '" . $this->db->escape($transaction_data['transaction_id']) . "', 57 `parent_id` = '" . $this->db->escape($transaction_data['parent_id']) . "', 58 `date_added` = NOW(), 59 `note` = '" . $this->db->escape($transaction_data['note']) . "', 60 `msgsubid` = '" . $this->db->escape($transaction_data['msgsubid']) . "', 61 `receipt_id` = '" . $this->db->escape($transaction_data['receipt_id']) . "', 62 `payment_type` = '" . $this->db->escape($transaction_data['payment_type']) . "', 63 `payment_status` = '" . $this->db->escape($transaction_data['payment_status']) . "', 64 `pending_reason` = '" . $this->db->escape($transaction_data['pending_reason']) . "', 65 `transaction_entity` = '" . $this->db->escape($transaction_data['transaction_entity']) . "', 66 `amount` = '" . (float)$transaction_data['amount'] . "', 67 `debug_data` = '" . $this->db->escape($transaction_data['debug_data']) . "'"); 68 } 69 70 public function paymentRequestInfo() { 71 72 $data['PAYMENTREQUEST_0_SHIPPINGAMT'] = ''; 73 $data['PAYMENTREQUEST_0_CURRENCYCODE'] = $this->session->data['currency']; 74 $data['PAYMENTREQUEST_0_PAYMENTACTION'] = $this->config->get('payment_pp_express_transaction'); 75 76 $i = 0; 77 $item_total = 0; 78 79 foreach ($this->cart->getProducts() as $item) { 80 $data['L_PAYMENTREQUEST_0_DESC' . $i] = ''; 81 82 $option_count = 0; 83 foreach ($item['option'] as $option) { 84 if ($option['type'] != 'file') { 85 $value = $option['value']; 86 } else { 87 $filename = $this->encryption->decrypt($this->config->get('config_encryption'), $option['value']); 88 $value = utf8_substr($filename, 0, utf8_strrpos($filename, '.')); 89 } 90 91 $data['L_PAYMENTREQUEST_0_DESC' . $i] .= ($option_count > 0 ? ', ' : '') . $option['name'] . ':' . (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value); 92 93 $option_count++; 94 } 95 96 $data['L_PAYMENTREQUEST_0_DESC' . $i] = substr($data['L_PAYMENTREQUEST_0_DESC' . $i], 0, 126); 97 98 $item_price = $this->currency->format($item['price'], $this->session->data['currency'], false, false); 99 100 $data['L_PAYMENTREQUEST_0_NAME' . $i] = $item['name']; 101 $data['L_PAYMENTREQUEST_0_NUMBER' . $i] = $item['model']; 102 $data['L_PAYMENTREQUEST_0_AMT' . $i] = $item_price; 103 104 $item_total += number_format($item_price * $item['quantity'], 2, '.', ''); 105 106 $data['L_PAYMENTREQUEST_0_QTY' . $i] = $item['quantity']; 107 108 $data['L_PAYMENTREQUEST_0_ITEMURL' . $i] = $this->url->link('product/product', 'product_id=' . $item['product_id']); 109 110 if ($this->config->get('config_cart_weight')) { 111 $weight = $this->weight->convert($item['weight'], $item['weight_class_id'], $this->config->get('config_weight_class_id')); 112 $data['L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE' . $i] = number_format($weight / $item['quantity'], 2, '.', ''); 113 $data['L_PAYMENTREQUEST_0_ITEMWEIGHTUNIT' . $i] = $this->weight->getUnit($this->config->get('config_weight_class_id')); 114 } 115 116 if ($item['length'] > 0 || $item['width'] > 0 || $item['height'] > 0) { 117 $unit = $this->length->getUnit($item['length_class_id']); 118 $data['L_PAYMENTREQUEST_0_ITEMLENGTHVALUE' . $i] = $item['length']; 119 $data['L_PAYMENTREQUEST_0_ITEMLENGTHUNIT' . $i] = $unit; 120 $data['L_PAYMENTREQUEST_0_ITEMWIDTHVALUE' . $i] = $item['width']; 121 $data['L_PAYMENTREQUEST_0_ITEMWIDTHUNIT' . $i] = $unit; 122 $data['L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE' . $i] = $item['height']; 123 $data['L_PAYMENTREQUEST_0_ITEMHEIGHTUNIT' . $i] = $unit; 124 } 125 126 $i++; 127 } 128 129 if (!empty($this->session->data['vouchers'])) { 130 foreach ($this->session->data['vouchers'] as $voucher) { 131 $item_total += $this->currency->format($voucher['amount'], $this->session->data['currency'], false, false); 132 133 $data['L_PAYMENTREQUEST_0_DESC' . $i] = ''; 134 $data['L_PAYMENTREQUEST_0_NAME' . $i] = $voucher['description']; 135 $data['L_PAYMENTREQUEST_0_NUMBER' . $i] = 'VOUCHER'; 136 $data['L_PAYMENTREQUEST_0_QTY' . $i] = 1; 137 $data['L_PAYMENTREQUEST_0_AMT' . $i] = $this->currency->format($voucher['amount'], $this->session->data['currency'], false, false); 138 $i++; 139 } 140 } 141 142 // Totals 143 $this->load->model('setting/extension'); 144 145 $totals = array(); 146 $taxes = $this->cart->getTaxes(); 147 $total = 0; 148 149 // Because __call can not keep var references so we put them into an array. 150 $total_data = array( 151 'totals' => &$totals, 152 'taxes' => &$taxes, 153 'total' => &$total 154 ); 155 156 // Display prices 157 if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) { 158 $sort_order = array(); 159 160 $results = $this->model_setting_extension->getExtensions('total'); 161 162 foreach ($results as $key => $value) { 163 $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); 164 } 165 166 array_multisort($sort_order, SORT_ASC, $results); 167 168 foreach ($results as $result) { 169 if ($this->config->get('total_' . $result['code'] . '_status')) { 170 $this->load->model('extension/total/' . $result['code']); 171 172 // We have to put the totals in an array so that they pass by reference. 173 $this->{'model_extension_total_' . $result['code']}->getTotal($total_data); 174 } 175 176 $sort_order = array(); 177 178 foreach ($totals as $key => $value) { 179 $sort_order[$key] = $value['sort_order']; 180 } 181 182 array_multisort($sort_order, SORT_ASC, $totals); 183 } 184 } 185 186 foreach ($total_data['totals'] as $total_row) { 187 if (!in_array($total_row['code'], array('total', 'sub_total'))) { 188 if ($total_row['value'] != 0) { 189 $item_price = $this->currency->format($total_row['value'], $this->session->data['currency'], false, false); 190 191 $data['L_PAYMENTREQUEST_0_NUMBER' . $i] = $total_row['code']; 192 $data['L_PAYMENTREQUEST_0_NAME' . $i] = $total_row['title']; 193 $data['L_PAYMENTREQUEST_0_AMT' . $i] = $this->currency->format($total_row['value'], $this->session->data['currency'], false, false); 194 $data['L_PAYMENTREQUEST_0_QTY' . $i] = 1; 195 196 $item_total = $item_total + $item_price; 197 $i++; 198 } 199 } 200 } 201 202 $data['PAYMENTREQUEST_0_ITEMAMT'] = number_format($item_total, 2, '.', ''); 203 $data['PAYMENTREQUEST_0_AMT'] = number_format($item_total, 2, '.', ''); 204 205 $z = 0; 206 207 $recurring_products = $this->cart->getRecurringProducts(); 208 209 if ($recurring_products) { 210 $this->load->language('extension/payment/pp_express'); 211 212 foreach ($recurring_products as $item) { 213 $data['L_BILLINGTYPE' . $z] = 'RecurringPayments'; 214 215 if ($item['recurring']['trial']) { 216 $trial_amt = $this->currency->format($this->tax->calculate($item['recurring']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'] . ' ' . $this->session->data['currency']; 217 $trial_text = sprintf($this->language->get('text_trial'), $trial_amt, $item['recurring']['trial_cycle'], $item['recurring']['trial_frequency'], $item['recurring']['trial_duration']); 218 } else { 219 $trial_text = ''; 220 } 221 222 $recurring_amt = $this->currency->format($this->tax->calculate($item['recurring']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'] . ' ' . $this->session->data['currency']; 223 $recurring_description = $trial_text . sprintf($this->language->get('text_recurring'), $recurring_amt, $item['recurring']['cycle'], $item['recurring']['frequency']); 224 225 if ($item['recurring']['duration'] > 0) { 226 $recurring_description .= sprintf($this->language->get('text_length'), $item['recurring']['duration']); 227 } 228 229 $data['L_BILLINGAGREEMENTDESCRIPTION' . $z] = $recurring_description; 230 $z++; 231 } 232 } 233 234 return $data; 235 } 236 237 public function getTotalCaptured($paypal_order_id) { 238 $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 `pending_reason` != 'paymentreview' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'"); 239 240 return $qry->row['amount']; 241 } 242 243 public function getTotalRefunded($paypal_order_id) { 244 $qry = $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'"); 245 246 return $qry->row['amount']; 247 } 248 249 public function getTransactionRow($transaction_id) { 250 $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_order_transaction` `pt` LEFT JOIN `" . DB_PREFIX . "paypal_order` `po` ON `pt`.`paypal_order_id` = `po`.`paypal_order_id` WHERE `pt`.`transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1"); 251 252 if ($qry->num_rows > 0) { 253 return $qry->row; 254 } else { 255 return false; 256 } 257 } 258 259 public function updateOrder($capture_status, $order_id) { 260 $this->db->query("UPDATE `" . DB_PREFIX . "paypal_order` SET `date_modified` = now(), `capture_status` = '" . $this->db->escape($capture_status) . "' WHERE `order_id` = '" . (int)$order_id . "'"); 261 } 262 263 public function call($data) { 264 if ($this->config->get('payment_pp_express_test')) { 265 $api_url = 'https://api-3t.sandbox.paypal.com/nvp'; 266 $api_user = $this->config->get('payment_pp_express_sandbox_username'); 267 $api_password = $this->config->get('payment_pp_express_sandbox_password'); 268 $api_signature = $this->config->get('payment_pp_express_sandbox_signature'); 269 } else { 270 $api_url = 'https://api-3t.paypal.com/nvp'; 271 $api_user = $this->config->get('payment_pp_express_username'); 272 $api_password = $this->config->get('payment_pp_express_password'); 273 $api_signature = $this->config->get('payment_pp_express_signature'); 274 } 275 276 $settings = array( 277 'USER' => $api_user, 278 'PWD' => $api_password, 279 'SIGNATURE' => $api_signature, 280 'VERSION' => '109.0', 281 'BUTTONSOURCE' => 'OpenCart_2.0_EC' 282 ); 283 284 $this->log($data, 'Call data'); 285 286 $defaults = array( 287 CURLOPT_POST => 1, 288 CURLOPT_HEADER => 0, 289 CURLOPT_URL => $api_url, 290 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", 291 CURLOPT_FRESH_CONNECT => 1, 292 CURLOPT_RETURNTRANSFER => 1, 293 CURLOPT_FORBID_REUSE => 1, 294 CURLOPT_TIMEOUT => 0, 295 CURLOPT_SSL_VERIFYPEER => 0, 296 CURLOPT_SSL_VERIFYHOST => 0, 297 CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&"), 298 ); 299 300 $ch = curl_init(); 301 302 curl_setopt_array($ch, $defaults); 303 304 if (!$result = curl_exec($ch)) { 305 $this->log(array('error' => curl_error($ch), 'errno' => curl_errno($ch)), 'cURL failed'); 306 } 307 308 $this->log($result, 'Result'); 309 310 curl_close($ch); 311 312 return $this->cleanReturn($result); 313 } 314 315 public function recurringPayments() { 316 /* 317 * Used by the checkout to state the module 318 * supports recurring recurrings. 319 */ 320 return true; 321 } 322 323 public function createToken($len = 32) { 324 $base = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789'; 325 $max = strlen($base)-1; 326 $activate_code = ''; 327 mt_srand((float)microtime()*1000000); 328 329 while (strlen($activate_code)<$len+1) { 330 $activate_code .= $base{mt_rand(0, $max)}; 331 } 332 333 return $activate_code; 334 } 335 336 public function log($data, $title = null) { 337 if ($this->config->get('payment_pp_express_debug')) { 338 $this->log->write('PayPal Express debug (' . $title . '): ' . json_encode($data)); 339 } 340 } 341 342 public function cleanReturn($data) { 343 $data = explode('&', $data); 344 345 $arr = array(); 346 347 foreach ($data as $k=>$v) { 348 $tmp = explode('=', $v); 349 $arr[$tmp[0]] = isset($tmp[1]) ? urldecode($tmp[1]) : ''; 350 } 351 352 return $arr; 353 } 354 }