WC_Gateway_PayPal_Advanced_AngellEYE

The PayPal for WooCommerce WC Gateway PayPal Advanced AngellEYE class.

Defined (1)

The class is defined in the following location(s).

/classes/wc-gateway-paypal-advanced-angelleye.php  
  1. class WC_Gateway_PayPal_Advanced_AngellEYE extends WC_Payment_Gateway { 
  2.  
  3. public $customer_id; 
  4.  
  5. public function __construct() { 
  6. $this->id = 'paypal_advanced'; 
  7.  
  8. $this->has_fields = true; 
  9. $this->home_url = is_ssl() ? home_url('/', 'https') : home_url('/'); //set the urls (cancel or return) based on SSL 
  10. $this->testurl = 'https://pilot-payflowpro.paypal.com'; 
  11. $this->liveurl = 'https://payflowpro.paypal.com'; 
  12. $this->relay_response_url = add_query_arg('wc-api', 'WC_Gateway_PayPal_Advanced_AngellEYE', $this->home_url); 
  13. $this->method_title = __('PayPal Advanced', 'paypal-for-woocommerce'); 
  14. $this->secure_token_id = ''; 
  15. $this->securetoken = ''; 
  16. $this->supports = array( 
  17. 'products',  
  18. 'refunds' 
  19. ); 
  20.  
  21. // Load the form fields. 
  22. $this->init_form_fields(); 
  23.  
  24. // Load the settings. 
  25. $this->init_settings(); 
  26.  
  27. $this->enable_tokenized_payments = $this->get_option('enable_tokenized_payments', 'no'); 
  28. if ($this->enable_tokenized_payments == 'yes' && !is_add_payment_method_page()) { 
  29. $this->supports = array( 
  30. 'subscriptions',  
  31. 'products',  
  32. 'refunds',  
  33. 'subscription_cancellation',  
  34. 'subscription_reactivation',  
  35. 'subscription_suspension',  
  36. 'subscription_amount_changes',  
  37. 'subscription_payment_method_change', // Subs 1.n compatibility. 
  38. 'subscription_payment_method_change_customer',  
  39. 'subscription_payment_method_change_admin',  
  40. 'subscription_date_changes',  
  41. 'multiple_subscriptions',  
  42. 'add_payment_method',  
  43. 'tokenization' 
  44. ); 
  45. $this->enabled = 'yes' === $this->get_option('enabled', 'no'); 
  46. $this->title = $this->get_option('title'); 
  47. $this->description = $this->get_option('description'); 
  48. $this->testmode = 'yes' === $this->get_option('testmode', 'yes'); 
  49. if ($this->testmode == false) { 
  50. $this->testmode = AngellEYE_Utility::angelleye_paypal_for_woocommerce_is_set_sandbox_product(); 
  51. $this->loginid = $this->get_option('loginid'); 
  52. $this->resellerid = $this->get_option('resellerid'); 
  53. $this->transtype = $this->get_option('transtype'); 
  54. $this->password = $this->get_option('password'); 
  55. $this->debug = 'yes' === $this->get_option('debug', 'no'); 
  56. $this->invoice_id_prefix = $this->get_option('invoice_prefix', 'WC-PPADV'); 
  57. $this->page_collapse_bgcolor = $this->get_option('page_collapse_bgcolor'); 
  58. $this->page_collapse_textcolor = $this->get_option('page_collapse_textcolor'); 
  59. $this->page_button_bgcolor = $this->get_option('page_button_bgcolor'); 
  60. $this->page_button_textcolor = $this->get_option('page_button_textcolor'); 
  61. $this->label_textcolor = $this->get_option('label_textcolor'); 
  62. $this->icon = $this->get_option('card_icon', plugins_url('/assets/images/cards.png', plugin_basename(dirname(__FILE__)))); 
  63. $this->is_encrypt = $this->get_option('is_encrypt', 'no'); 
  64. $this->loginid = $this->get_option('loginid'); 
  65. $this->user = $this->get_option('user', $this->loginid); 
  66. $this->mobilemode = $this->get_option('mobilemode', 'yes'); 
  67. if (is_ssl()) { 
  68. $this->icon = preg_replace("/^http:/i", "https:", $this->icon); 
  69. $this->icon = apply_filters('woocommerce_paypal_advanced_icon', $this->icon); 
  70. $this->mobilemode = 'yes' === $this->get_option('mobilemode', 'yes'); 
  71. $this->layout = $this->get_option('layout', 'C'); 
  72. switch ($this->layout) { 
  73. case 'A': $this->layout = 'TEMPLATEA'; 
  74. break; 
  75. case 'B': $this->layout = 'TEMPLATEB'; 
  76. break; 
  77. case 'C': $this->layout = 'MINLAYOUT'; 
  78. break; 
  79.  
  80.  
  81. $this->hostaddr = $this->testmode == true ? $this->testurl : $this->liveurl; 
  82. $this->softdescriptor = $this->get_option('softdescriptor', ''); 
  83.  
  84. if ($this->debug == 'yes') 
  85. $this->log = new WC_Logger(); 
  86.  
  87. // Hooks 
  88. add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); 
  89. add_action('woocommerce_receipt_paypal_advanced', array($this, 'receipt_page')); 
  90. add_action('woocommerce_api_wc_gateway_paypal_advanced_angelleye', array($this, 'relay_response')); 
  91. add_filter('woocommerce_settings_api_sanitized_fields_' . $this->id, array($this, 'angelleye_paypal_advanced_encrypt_gateway_api'), 10, 1); 
  92. $this->customer_id; 
  93.  
  94. /** 
  95. * Check if required fields for configuring the gateway are filled up by the administrator 
  96. * @access public 
  97. * @return void 
  98. * */ 
  99. public function checks() { 
  100. if (!$this->is_valid_currency() || $this->enabled == false) { 
  101. return; 
  102. if (!$this->loginid) { 
  103. echo '<div class="inline error"><p>' . sprintf(__('Paypal Advanced error: Please enter your PayPal Advanced Account Merchant Login.', 'paypal-for-woocommerce')) . '</p></div>'; 
  104. } elseif (!$this->resellerid) { 
  105. echo '<div class="inline error"><p>' . sprintf(__('Paypal Advanced error: Please enter your PayPal Advanced Account Partner.', 'paypal-for-woocommerce')) . '</p></div>'; 
  106. } elseif (!$this->password) { 
  107. echo '<div class="inline error"><p>' . sprintf(__('Paypal Advanced error: Please enter your PayPal Advanced Account Password.', 'paypal-for-woocommerce')) . '</p></div>'; 
  108.  
  109. /** 
  110. * redirect_to - redirects to the url based on layout type 
  111. * @access public 
  112. * @return javascript code to redirect the parent to a page 
  113. */ 
  114. public function redirect_to($redirect_url) { 
  115. // Clean 
  116. @ob_clean(); 
  117.  
  118. // Header 
  119. header('HTTP/1.1 200 OK'); 
  120.  
  121. //redirect to the url based on layout type 
  122. if ($this->layout != 'MINLAYOUT') { 
  123. wp_redirect($redirect_url); 
  124. } else { 
  125. echo "<script>window.parent.location.href='" . $redirect_url . "';</script>"; 
  126. exit; 
  127.  
  128. /** 
  129. * inquiry_transaction - Performs inquiry transaction 
  130. * @access private 
  131. * @param WC_Order $order 
  132. * @param int $order_id 
  133. * @return result code of the inquiry transaction 
  134. */ 
  135. private function inquiry_transaction($order, $order_id) { 
  136.  
  137. //inquire transaction, whether it is really paid or not 
  138. $paypal_args = array( 
  139. 'USER' => $this->user,  
  140. 'VENDOR' => $this->loginid,  
  141. 'PARTNER' => $this->resellerid,  
  142. 'PWD[' . strlen($this->password) . ']' => $this->password,  
  143. 'ORIGID' => $_POST['PNREF'],  
  144. 'TENDER' => 'C',  
  145. 'TRXTYPE' => 'I',  
  146. 'BUTTONSOURCE' => 'AngellEYE_SP_WooCommerce' 
  147. ); 
  148.  
  149. $postData = ''; //stores the post data string 
  150. foreach ($paypal_args as $key => $val) { 
  151. $postData .= '&' . $key . '=' . $val; 
  152.  
  153. $postData = trim($postData, '&'); 
  154.  
  155. /** Using Curl post necessary information to the Paypal Site to generate the secured token */ 
  156. $response = wp_remote_post($this->hostaddr, array( 
  157. 'method' => 'POST',  
  158. 'body' => $postData,  
  159. 'timeout' => 70,  
  160. 'user-agent' => 'Woocommerce ' . WC_VERSION,  
  161. 'httpversion' => '1.1',  
  162. 'headers' => array('host' => 'www.paypal.com') 
  163. )); 
  164. if (is_wp_error($response)) { 
  165. throw new Exception(__('There was a problem connecting to the payment gateway.', 'paypal-for-woocommerce')); 
  166. if (empty($response['body'])) { 
  167. throw new Exception(__('Empty response.', 'paypal-for-woocommerce')); 
  168.  
  169. $inquiry_result_arr = array(); //stores the response in array format 
  170. parse_str($response['body'], $inquiry_result_arr); 
  171.  
  172. if ($inquiry_result_arr['RESULT'] == 0 && ($inquiry_result_arr['RESPMSG'] == 'Approved' || $inquiry_result_arr['RESPMSG'] == 'Verified')) { 
  173. $order->add_order_note(sprintf(__('Received result of Inquiry Transaction for the (Order: %s) and is successful', 'paypal-for-woocommerce'), $order->get_order_number())); 
  174. return 'Approved'; 
  175. } else { 
  176. $order->add_order_note(sprintf(__('Received result of Inquiry Transaction for the (Order: %s) and with error:%s', 'paypal-for-woocommerce'), $order->get_order_number(), $inquiry_result_arr['RESPMSG'])); 
  177. return 'Error'; 
  178.  
  179. /** 
  180. * success_handler - Handles the successful transaction 
  181. * @access private 
  182. * @param WC_Order $order 
  183. * @param int $order_id 
  184. * @param bool $silent_post 
  185. * @return 
  186. */ 
  187. private function success_handler($order, $order_id, $silent_post) { 
  188. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  189. $_secure_token = $old_wc ? get_post_meta($order->id, '_secure_token', true) : get_post_meta($order->get_id(), '_secure_token', true); 
  190. if ($_secure_token == $_REQUEST['SECURETOKEN']) { 
  191. if ($this->debug == 'yes') { 
  192. $this->log->add('paypal_advanced', __('Relay Response Tokens Match', 'paypal-for-woocommerce')); 
  193. } else { // Redirect to homepage, if any invalid request or hack 
  194. if ($this->debug == 'yes') { 
  195. $this->log->add('paypal_advanced', __('Relay Response Tokens Mismatch', 'paypal-for-woocommerce')); 
  196. //redirect to the checkout page, if not silent post 
  197. if ($silent_post === false) 
  198. $this->redirect_to($order->get_checkout_payment_url(true)); 
  199. exit; 
  200.  
  201. // Add order note 
  202. $order->add_order_note(sprintf(__('PayPal Advanced payment completed (Order: %s). Transaction number/ID: %s.', 'paypal-for-woocommerce'), $order->get_order_number(), $_POST['PNREF'])); 
  203.  
  204. $inq_result = $this->inquiry_transaction($order, $order_id); 
  205.  
  206. // Handle response 
  207. if ($inq_result == 'Approved') {//if approved 
  208. // Payment complete 
  209. $this->save_payment_token($order, $_POST['PNREF']); 
  210. $order->payment_complete($_POST['PNREF']); 
  211. do_action('before_save_payment_token', $order_id); 
  212. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  213. $is_save_payment_method = $old_wc ? get_post_meta($order->id, '_is_save_payment_method', true) : get_post_meta($order->get_id(), '_is_save_payment_method', true); 
  214. if ($is_save_payment_method == 'yes') { 
  215. $customer_id = $order->get_user_id(); 
  216. $TRANSACTIONID = $_POST['PNREF']; 
  217. $token = new WC_Payment_Token_CC(); 
  218. $token->set_user_id($customer_id); 
  219. $token->set_token($TRANSACTIONID); 
  220. $token->set_gateway_id($this->id); 
  221. $token->set_card_type('PayPal'); 
  222. $token->set_last4($_POST['ACCT']); 
  223. $token->set_expiry_month(date('m')); 
  224. $token->set_expiry_year(date('Y', strtotime('+1 year'))); 
  225. $save_result = $token->save(); 
  226. if ($save_result) { 
  227. $order->add_payment_token($token); 
  228. // Remove cart 
  229. WC()->cart->empty_cart(); 
  230.  
  231. // Add order note 
  232. $order->add_order_note(sprintf(__('Payment completed for the (Order: %s)', 'paypal-for-woocommerce'), $order->get_order_number())); 
  233.  
  234. //log the completeion 
  235. if ($this->debug == 'yes') 
  236. $this->log->add('paypal_advanced', sprintf(__('Payment completed for the (Order: %s)', 'paypal-for-woocommerce'), $order->get_order_number())); 
  237.  
  238. //redirect to the thanks page, if not silent post 
  239. if ($silent_post === false) { 
  240. $this->redirect_to($this->get_return_url($order)); 
  241.  
  242. /** 
  243. * error_handler - Handles the error transaction 
  244. * @access private 
  245. * @param WC_Order $order 
  246. * @param int $order_id 
  247. * @param bool $silent_post 
  248. * @return 
  249. */ 
  250. private function error_handler($order, $order_id, $silent_post) { 
  251.  
  252. // 12-0 messages 
  253. wc_clear_notices(); 
  254. // Add error 
  255. wc_add_notice(__('Error:', 'paypal-for-woocommerce') . ' "' . urldecode($_POST['RESPMSG']) . '"', 'error'); 
  256.  
  257. //redirect to the checkout page, if not silent post 
  258. if ($silent_post === false) { 
  259. $this->redirect_to($order->get_checkout_payment_url(true)); 
  260.  
  261. /** 
  262. * cancel_handler - Handles the cancel transaction 
  263. * @access private 
  264. * @param WC_Order $order 
  265. * @param int $order_id 
  266. * @return 
  267. */ 
  268. private function cancel_handler($order, $order_id) { 
  269. wp_redirect($order->get_cancel_order_url()); 
  270. exit; 
  271.  
  272. /** 
  273. * decline_handler - Handles the decline transaction 
  274. * @access private 
  275. * @param WC_Order $order 
  276. * @param int $order_id 
  277. * @param bool $silent_post 
  278. * @return 
  279. */ 
  280. private function decline_handler($order, $order_id, $silent_post) { 
  281.  
  282.  
  283. $order->update_status('failed', __('Payment failed via PayPal Advanced because of.', 'paypal-for-woocommerce') . ' ' . $_POST['RESPMSG']); 
  284.  
  285. if ($this->debug == 'yes') { 
  286. $this->log->add('paypal_advanced', sprintf(__('Status has been changed to failed for order %s', 'paypal-for-woocommerce'), $order->get_order_number())); 
  287. if ($this->debug == 'yes') { 
  288. $this->log->add('paypal_advanced', sprintf(__('Error Occurred while processing %s : %s, status: %s', 'paypal-for-woocommerce'), $order->get_order_number(), urldecode($_POST['RESPMSG']), $_POST['RESULT'])); 
  289. $this->error_handler($order, $order_id, $silent_post); 
  290.  
  291. /** 
  292. * Relay response - Checks the payment transaction reponse based on that either completes the transaction or shows thows the exception and show sthe error 
  293. * @access public 
  294. * @return javascript code to redirect the parent to a page 
  295. */ 
  296. public function relay_response() { 
  297.  
  298. //define a variable to indicate whether it is a silent post or return 
  299. if (isset($_REQUEST['silent']) && $_REQUEST['silent'] == 'true') { 
  300. $silent_post = true; 
  301. } else { 
  302. $silent_post = false; 
  303.  
  304. //log the event 
  305. if ($silent_post === true) { 
  306. $this->add_log(sprintf(__('Silent Relay Response Triggered: %s', 'paypal-for-woocommerce'), print_r($_REQUEST, true))); 
  307. } else { 
  308. $this->add_log(sprintf(__('Relay Response Triggered: %s', 'paypal-for-woocommerce'), print_r($_REQUEST, true))); 
  309. //if valid request 
  310. if (!isset($_REQUEST['INVOICE'])) { // Redirect to homepage, if any invalid request or hack 
  311. //if not silent post redirect it to home page otherwise just exit 
  312. if ($silent_post === false) { 
  313. wp_redirect(home_url('/')); 
  314. exit; 
  315. // get Order ID 
  316. $order_id = $_REQUEST['USER1']; 
  317.  
  318. // Create order object 
  319. $order = new WC_Order($order_id); 
  320.  
  321. //check for the status of the order, if completed or processing, redirect to thanks page. This case happens when silentpost is on 
  322. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  323. if($old_wc) { 
  324. $status = isset($order->status) ? $order->status : $order->get_status(); 
  325. } else { 
  326. $status = $order->get_status(); 
  327.  
  328. if ($status == 'processing' || $status == 'completed') { 
  329. // Log 
  330. if ($this->debug == "yes") { 
  331. $this->log->add('paypal_advanced', sprintf(__('Redirecting to Thank You Page for order %s', 'paypal-for-woocommerce'), $order->get_order_number())); 
  332.  
  333. //redirect to the thanks page, if not silent post 
  334. if ($silent_post === false) { 
  335. $this->redirect_to($this->get_return_url($order)); 
  336.  
  337. //define RESULT, if not provided in case of cancel, define with -1 
  338. if (isset($_REQUEST['cancel_ec_trans']) && $_REQUEST['cancel_ec_trans'] == 'true') { 
  339. $_REQUEST['RESULT'] = -1; 
  340. //handle the successful transaction 
  341. switch ($_REQUEST['RESULT']) { 
  342.  
  343. case 0 : 
  344. //handle exceptional cases 
  345. if ($_REQUEST['RESPMSG'] == 'Approved' || $_REQUEST['RESPMSG'] == 'Verified') { 
  346. $this->success_handler($order, $order_id, $silent_post); 
  347. } else if ($_REQUEST['RESPMSG'] == 'Declined') { 
  348. $this->decline_handler($order, $order_id, $silent_post); 
  349. } else { 
  350. $this->error_handler($order, $order_id, $silent_post); 
  351. break; 
  352. case 12: 
  353. $this->decline_handler($order, $order_id, $silent_post); 
  354. break; 
  355. case -1: 
  356. $this->cancel_handler($order, $order_id); 
  357. break; 
  358. default: 
  359. //handles error order 
  360. $this->error_handler($order, $order_id, $silent_post); 
  361. break; 
  362.  
  363.  
  364. /** 
  365. * Gets the secured token by passing all the required information to PayPal site 
  366. * @param order an WC_ORDER Object 
  367. * @return secure_token as string 
  368. */ 
  369. public function get_secure_token($order) { 
  370. static $length_error = 0; 
  371. $this->add_log(sprintf(__('Requesting for the Secured Token for the order %s', 'paypal-for-woocommerce'), $order->get_order_number())); 
  372. // Generate unique id 
  373. $this->secure_token_id = uniqid(substr($_SERVER['HTTP_HOST'], 0, 9), true); 
  374.  
  375. // Prepare paypal_ars array to pass to paypal to generate the secure token 
  376. $paypal_args = array(); 
  377.  
  378. //override the layout with mobile template, if browsed from mobile if the exitsing layout is C or MINLAYOUT 
  379. if (($this->layout == 'MINLAYOUT' || $this->layout == 'C') && $this->mobilemode == true) { 
  380. $template = wp_is_mobile() ? "MOBILE" : $this->layout; 
  381. } else { 
  382. $template = $this->layout; 
  383.  
  384. $this->transtype = ($order->get_total() == 0 ) ? 'A' : $this->transtype; 
  385. $shipping_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(); 
  386. $shipping_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(); 
  387. $shipping_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(); 
  388. $shipping_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(); 
  389. $shiptostreet = $shipping_address_1 . ' ' . $shipping_address_2; 
  390. $shipping_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(); 
  391. $shipping_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(); 
  392. $shipping_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(); 
  393. $shipping_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(); 
  394. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  395.  
  396. $billing_company = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(); 
  397. $billing_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  398. $billing_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  399. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  400. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  401. $billtostreet = $billing_address_1 . ' ' . $billing_address_2; 
  402. $billing_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_city : $order->get_billing_city(); 
  403. $billing_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_postcode : $order->get_billing_postcode(); 
  404. $billing_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_country : $order->get_billing_country(); 
  405. $billing_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_state : $order->get_billing_state(); 
  406. $billing_email = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_email : $order->get_billing_email(); 
  407. $billing_phone = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_phone : $order->get_billing_phone(); 
  408.  
  409. $paypal_args = array( 
  410. 'VERBOSITY' => 'HIGH',  
  411. 'USER' => $this->user,  
  412. 'VENDOR' => $this->loginid,  
  413. 'PARTNER' => $this->resellerid,  
  414. 'PWD[' . strlen($this->password) . ']' => $this->password,  
  415. 'SECURETOKENID' => $this->secure_token_id,  
  416. 'CREATESECURETOKEN' => 'Y',  
  417. 'TRXTYPE' => $this->transtype,  
  418. 'CUSTREF' => $order->get_order_number(),  
  419. 'USER1' => $order_id,  
  420. 'INVNUM' => $this->invoice_id_prefix . preg_replace("/[^a-zA-Z0-9]/", "", str_replace("#", "", $order->get_order_number())),  
  421. 'AMT' => number_format($order->get_total(), 2, '.', ''),  
  422. 'FREIGHTAMT' => '',  
  423. 'COMPANYNAME[' . strlen($billing_company) . ']' => $billing_company,  
  424. 'CURRENCY' => version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency(),  
  425. 'EMAIL' => $billing_email,  
  426. 'BILLTOFIRSTNAME[' . strlen($billing_first_name) . ']' => $billing_first_name,  
  427. 'BILLTOLASTNAME[' . strlen($billing_last_name) . ']' => $billing_last_name,  
  428. 'BILLTOSTREET[' . strlen($billtostreet) . ']' => $billtostreet,  
  429. 'BILLTOCITY[' . strlen($billing_city) . ']' => $billing_city,  
  430. 'BILLTOSTATE[' . strlen($billing_state) . ']' => $billing_state,  
  431. 'BILLTOZIP' => $billing_postcode,  
  432. 'BILLTOCOUNTRY[' . strlen($billing_country) . ']' => $billing_country,  
  433. 'BILLTOEMAIL' => $billing_email,  
  434. 'BILLTOPHONENUM' => $billing_phone,  
  435. 'SHIPTOFIRSTNAME[' . strlen($shipping_first_name) . ']' => $shipping_first_name,  
  436. 'SHIPTOLASTNAME[' . strlen($shipping_last_name) . ']' => $shipping_last_name,  
  437. 'SHIPTOSTREET[' . strlen($shiptostreet) . ']' => $shiptostreet,  
  438. 'SHIPTOCITY[' . strlen($shipping_city) . ']' => $shipping_city,  
  439. 'SHIPTOZIP' => $shipping_postcode,  
  440. 'SHIPTOCOUNTRY[' . strlen($shipping_country) . ']' => $shipping_country,  
  441. 'BUTTONSOURCE' => 'AngellEYE_SP_WooCommerce',  
  442. 'RETURNURL[' . strlen($this->relay_response_url) . ']' => $this->relay_response_url,  
  443. 'URLMETHOD' => 'POST',  
  444. 'TEMPLATE' => $template,  
  445. 'PAGECOLLAPSEBGCOLOR' => ltrim($this->page_collapse_bgcolor, '#'),  
  446. 'PAGECOLLAPSETEXTCOLOR' => ltrim($this->page_collapse_textcolor, '#'),  
  447. 'PAGEBUTTONBGCOLOR' => ltrim($this->page_button_bgcolor, '#'),  
  448. 'PAGEBUTTONTEXTCOLOR' => ltrim($this->page_button_textcolor, '#'),  
  449. 'LABELTEXTCOLOR' => ltrim($this->settings['label_textcolor'], '#'),  
  450. 'MERCHDESCR' => $this->softdescriptor 
  451. ); 
  452.  
  453. //handle empty state exception e.g. Denmark 
  454. if (empty($shipping_state)) { 
  455. //replace with city 
  456. $paypal_args['SHIPTOSTATE[' . strlen($shipping_city) . ']'] = $shipping_city; 
  457. } else { 
  458. //retain state 
  459. $paypal_args['SHIPTOSTATE[' . strlen($shipping_state) . ']'] = $shipping_state; 
  460.  
  461. // Determine the ERRORURL, CANCELURL and SILENTPOSTURL 
  462. $cancelurl = add_query_arg('wc-api', 'WC_Gateway_PayPal_Advanced_AngellEYE', add_query_arg('cancel_ec_trans', 'true', $this->home_url)); 
  463. $paypal_args['CANCELURL[' . strlen($cancelurl) . ']'] = $cancelurl; 
  464.  
  465. $errorurl = add_query_arg('wc-api', 'WC_Gateway_PayPal_Advanced_AngellEYE', add_query_arg('error', 'true', $this->home_url)); 
  466. $paypal_args['ERRORURL[' . strlen($errorurl) . ']'] = $errorurl; 
  467.  
  468. $silentposturl = add_query_arg('wc-api', 'WC_Gateway_PayPal_Advanced_AngellEYE', add_query_arg('silent', 'true', $this->home_url)); 
  469. $paypal_args['SILENTPOSTURL[' . strlen($silentposturl) . ']'] = $silentposturl; 
  470.  
  471. // If prices include tax or have order discounts, send the whole order as a single item 
  472. $is_prices_include_tax = version_compare(WC_VERSION, '3.0', '<') ? 'yes' === $order->prices_include_tax : $order->get_prices_include_tax(); 
  473.  
  474.  
  475. if (($is_prices_include_tax || $order->get_total_discount() > 0 || $length_error > 1) && $order->get_subtotal() > 0) { 
  476.  
  477. // Don't pass items - paypal borks tax due to prices including tax. PayPal has no option for tax inclusive pricing sadly. Pass 1 item for the order items overall 
  478. $item_names = array(); 
  479.  
  480. if (sizeof($order->get_items()) > 0) { 
  481.  
  482. if ($length_error <= 1) { 
  483. foreach ($order->get_items() as $item) { 
  484. if ($item['qty']) { 
  485. $item_names[] = $item['name'] . ' x ' . $item['qty']; 
  486. } else { 
  487. $item_names[] = "All selected items, refer to Woocommerce order details"; 
  488. $items_str = sprintf(__('Order %s', 'paypal-for-woocommerce'), $order->get_order_number()) . " - " . implode(', ', $item_names); 
  489. $items_names_str = $this->paypal_advanced_item_name($items_str); 
  490. $items_desc_str = $this->paypal_advanced_item_desc($items_str); 
  491. $paypal_args['L_NAME0[' . strlen($items_names_str) . ']'] = $items_names_str; 
  492. $paypal_args['L_DESC0[' . strlen($items_desc_str) . ']'] = $items_desc_str; 
  493. $paypal_args['L_QTY0'] = 1; 
  494. if ($order->get_subtotal() == 0) { 
  495. $paypal_args['L_COST0'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  496. } else { 
  497. $paypal_args['FREIGHTAMT'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  498. $paypal_args['L_COST0'] = number_format($order->get_total() - round(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2), 2, '.', ''); 
  499.  
  500. //determine ITEMAMT 
  501. $paypal_args['ITEMAMT'] = $paypal_args['L_COST0'] * $paypal_args['L_QTY0']; 
  502. } else { 
  503.  
  504.  
  505. // Tax 
  506. $paypal_args['TAXAMT'] = $order->get_total_tax(); 
  507.  
  508. //ITEM AMT, total amount 
  509. $paypal_args['ITEMAMT'] = 0; 
  510.  
  511.  
  512. // Cart Contents 
  513. $item_loop = 0; 
  514. if (sizeof($order->get_items()) > 0 && $order->get_subtotal() > 0) { 
  515. foreach ($order->get_items() as $item) { 
  516. if ($item['qty']) { 
  517.  
  518. $product = $order->get_product_from_item($item); 
  519.  
  520. $item_name = $item['name']; 
  521.  
  522. //create order meta object and get the meta data as string 
  523. $item_meta = new WC_order_item_meta($item['item_meta']); 
  524. if ($length_error == 0 && $meta = $item_meta->display(true, true)) { 
  525. $item_name .= ' (' . $meta . ')'; 
  526. $item_name = $this->paypal_advanced_item_name($item_name); 
  527. $paypal_args['L_NAME' . $item_loop . '[' . strlen($item_name) . ']'] = $item_name; 
  528. if ($product->get_sku()) 
  529. $paypal_args['L_SKU' . $item_loop] = $product->get_sku(); 
  530. $paypal_args['L_QTY' . $item_loop] = $item['qty']; 
  531. $paypal_args['L_COST' . $item_loop] = $order->get_item_total($item, false, false); /** No Tax , No Round) */ 
  532. $paypal_args['L_TAXAMT' . $item_loop] = $order->get_item_tax($item, false); /** No Round it */ 
  533.  
  534. //calculate ITEMAMT 
  535. $paypal_args['ITEMAMT'] += $order->get_line_total($item, false, false); /** No tax, No Round */ 
  536.  
  537. $item_loop++; 
  538. } else { 
  539. $paypal_args['L_NAME0'] = sprintf(__('Shipping via %s', 'woocommerce'), $order->get_shipping_method()); 
  540. $paypal_args['L_QTY0'] = 1; 
  541. $paypal_args['L_COST0'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  542. $paypal_args['ITEMAMT'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  543.  
  544. try { 
  545.  
  546.  
  547. $postData = ''; 
  548. $logData = ''; 
  549.  
  550. foreach ($paypal_args as $key => $val) { 
  551.  
  552. $postData .= '&' . $key . '=' . $val; 
  553. if (strpos($key, 'PWD') === 0) { 
  554. $logData .= '&PWD=XXXX'; 
  555. } else { 
  556. $logData .= '&' . $key . '=' . $val; 
  557.  
  558. $postData = trim($postData, '&'); 
  559.  
  560.  
  561. // Log 
  562. if ($this->debug == 'yes') { 
  563.  
  564. $logData = trim($logData, '&'); 
  565. $this->log->add('paypal_advanced', sprintf(__('Requesting for the Secured Token for the order %s with following URL and Paramaters: %s', 'paypal-for-woocommerce'), $order->get_order_number(), $this->hostaddr . '?' . $logData)); 
  566.  
  567. /** Using Curl post necessary information to the Paypal Site to generate the secured token */ 
  568. $response = wp_remote_post($this->hostaddr, array( 
  569. 'method' => 'POST',  
  570. 'body' => apply_filters('angelleye_woocommerce_paypal_advanced_create_secure_token_request_args', $postData),  
  571. 'timeout' => 70,  
  572. 'user-agent' => 'WooCommerce ' . WC_VERSION,  
  573. 'httpversion' => '1.1',  
  574. 'headers' => array('host' => 'www.paypal.com') 
  575. )); 
  576.  
  577. //if error occurs, throw exception with the error message 
  578. if (is_wp_error($response)) { 
  579.  
  580. throw new Exception($response->get_error_message()); 
  581. if (empty($response['body'])) { 
  582. throw new Exception(__('Empty response.', 'paypal-for-woocommerce')); 
  583.  
  584. /** Parse and assign to array */ 
  585.  
  586. parse_str($response['body'], $arr); 
  587.  
  588. // Handle response 
  589. if ($arr['RESULT'] > 0) { 
  590. // raise exception 
  591. throw new Exception(__('There was an error processing your order - ' . $arr['RESPMSG'], 'paypal-for-woocommerce')); 
  592. } else {//return the secure token 
  593. return $arr['SECURETOKEN']; 
  594. } catch (Exception $e) { 
  595. if ($order->has_status(array('pending', 'failed'))) { 
  596. $this->send_failed_order_email($order_id); 
  597. $this->add_log(sprintf(__('Secured Token generation failed for the order %s with error: %s', 'paypal-for-woocommerce'), $order->get_order_number(), $e->getMessage())); 
  598. if ($arr['RESULT'] != 7) { 
  599. wc_add_notice(__('Error:', 'paypal-for-woocommerce') . ' "' . $e->getMessage() . '"', 'error'); 
  600. $length_error = 0; 
  601. return; 
  602. } else { 
  603. $this->add_log(sprintf(__('Secured Token generation failed for the order %s with error: %s', 'paypal-for-woocommerce'), $order->get_order_number(), $e->getMessage())); 
  604. $length_error++; 
  605. return $this->get_secure_token($order); 
  606.  
  607. /** 
  608. * Check if this gateway is enabled and available in the user's country 
  609. * @access public 
  610. * @return boolean 
  611. */ 
  612. public function is_available() { 
  613.  
  614. //if enabled checkbox is checked 
  615. if ($this->enabled == true) { 
  616. if (!in_array(get_woocommerce_currency(), apply_filters('woocommerce_paypal_advanced_allowed_currencies', array('USD', 'CAD')))) { 
  617. return false; 
  618. if (!$this->user || !$this->loginid) { 
  619. return false; 
  620. return true; 
  621. } else { 
  622. return false; 
  623.  
  624. public function is_valid_currency() { 
  625. return in_array(get_woocommerce_currency(), apply_filters('woocommerce_paypal_advanced_supported_currencies', array('USD', 'CAD'))); 
  626.  
  627. /** 
  628. * Admin Panel Options 
  629. * - Settings 
  630. * @access public 
  631. * @return void 
  632. */ 
  633. public function admin_options() { 
  634. ?> 
  635. <h3><?php _e('PayPal Advanced', 'paypal-for-woocommerce'); ?></h3> 
  636. <p><?php _e('PayPal Payments Advanced uses an iframe to seamlessly integrate PayPal hosted pages into the checkout process.', 'paypal-for-woocommerce'); ?></p> 
  637. <table class="form-table"> 
  638. <?php 
  639. //if user's currency is USD 
  640.  
  641. if (!in_array(get_woocommerce_currency(), array('USD', 'CAD'))) { 
  642. ?> 
  643. <div class="inline error"><p><strong><?php _e('Gateway Disabled', 'paypal-for-woocommerce'); ?></strong>: <?php _e('PayPal does not support your store currency.', 'paypal-for-woocommerce'); ?></p></div> 
  644. <?php 
  645. return; 
  646. } else { 
  647. // Generate the HTML For the settings form. 
  648. $this->checks(); 
  649. $this->generate_settings_html(); 
  650.  
  651. wp_enqueue_script('wp-color-picker'); 
  652. wp_enqueue_style('wp-color-picker'); 
  653. ?> 
  654. </table><!--/.form-table--> 
  655. <script type="text/javascript"> 
  656. jQuery(document).ready(function ($) { 
  657. jQuery('.paypal_for_woocommerce_color_field').wpColorPicker(); 
  658. }); 
  659. </script> 
  660. <?php 
  661.  
  662. // End admin_options() 
  663.  
  664. /** 
  665. * Initialise Gateway Settings Form Fields 
  666. * @access public 
  667. * @return void 
  668. */ 
  669. public function init_form_fields() { 
  670.  
  671. $this->form_fields = array( 
  672. 'enabled' => array( 
  673. 'title' => __('Enable/Disable', 'paypal-for-woocommerce'),  
  674. 'type' => 'checkbox',  
  675. 'label' => __('Enable PayPal Advanced', 'paypal-for-woocommerce'),  
  676. 'default' => 'no' 
  677. ),  
  678. 'title' => array( 
  679. 'title' => __('Title', 'paypal-for-woocommerce'),  
  680. 'type' => 'text',  
  681. 'description' => __('This controls the title which the user sees during checkout.', 'paypal-for-woocommerce'),  
  682. 'default' => __('PayPal Advanced', 'paypal-for-woocommerce') 
  683. ),  
  684. 'description' => array( 
  685. 'title' => __('Description', 'paypal-for-woocommerce'),  
  686. 'type' => 'text',  
  687. 'description' => __('This controls the description which the user sees during checkout.', 'paypal-for-woocommerce'),  
  688. 'default' => __('PayPal Advanced description', 'paypal-for-woocommerce') 
  689. ),  
  690. 'loginid' => array( 
  691. 'title' => __('Merchant Login', 'paypal-for-woocommerce'),  
  692. 'type' => 'text',  
  693. 'description' => '',  
  694. 'default' => '' 
  695. ),  
  696. 'resellerid' => array( 
  697. 'title' => __('Partner', 'paypal-for-woocommerce'),  
  698. 'type' => 'text',  
  699. 'description' => __('Enter your PayPal Advanced Partner. If you purchased the account directly from PayPal, use PayPal.', 'paypal-for-woocommerce'),  
  700. 'default' => '' 
  701. ),  
  702. 'user' => array( 
  703. 'title' => __('User (or Merchant Login if no designated user is set up for the account)', 'paypal-for-woocommerce'),  
  704. 'type' => 'text',  
  705. 'description' => __('Enter your PayPal Advanced user account for this site.', 'paypal-for-woocommerce'),  
  706. 'default' => '' 
  707. ),  
  708. 'password' => array( 
  709. 'title' => __('Password', 'paypal-for-woocommerce'),  
  710. 'type' => 'password',  
  711. 'description' => __('Enter your PayPal Advanced account password.', 'paypal-for-woocommerce'),  
  712. 'default' => '' 
  713. ),  
  714. 'enable_tokenized_payments' => array( 
  715. 'title' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  716. 'label' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  717. 'type' => 'checkbox',  
  718. 'description' => __('Allow buyers to securely save payment details to their account for quick checkout / auto-ship orders in the future.', 'paypal-for-woocommerce'),  
  719. 'default' => 'no',  
  720. 'class' => 'enable_tokenized_payments' 
  721. ),  
  722. 'softdescriptor' => array( 
  723. 'title' => __('Credit Card Statement Name', 'paypal-for-woocommerce'),  
  724. 'type' => 'text',  
  725. 'description' => __('The value entered here will be displayed on the buyer\'s credit card statement.', 'paypal-for-woocommerce'),  
  726. 'default' => '',  
  727. 'desc_tip' => true,  
  728. ),  
  729. 'testmode' => array( 
  730. 'title' => __('PayPal sandbox', 'paypal-for-woocommerce'),  
  731. 'type' => 'checkbox',  
  732. 'label' => __('Enable PayPal sandbox', 'paypal-for-woocommerce'),  
  733. 'default' => 'yes',  
  734. 'description' => sprintf(__('PayPal sandbox can be used to test payments. Sign up for a developer account <a href="%s">here</a>', 'paypal-for-woocommerce'), 'https://developer.paypal.com/'),  
  735. ),  
  736. 'transtype' => array( 
  737. 'title' => __('Transaction Type', 'paypal-for-woocommerce'),  
  738. 'type' => 'select',  
  739. 'label' => __('Transaction Type', 'paypal-for-woocommerce'),  
  740. 'default' => 'S',  
  741. 'description' => '',  
  742. 'options' => array('A' => 'Authorization', 'S' => 'Sale') 
  743. ),  
  744. 'layout' => array( 
  745. 'title' => __('Layout', 'paypal-for-woocommerce'),  
  746. 'type' => 'select',  
  747. 'label' => __('Layout', 'paypal-for-woocommerce'),  
  748. 'default' => 'C',  
  749. 'description' => __('Layouts A and B redirect to PayPal\'s website for the user to pay. <br/>Layout C (recommended) is a secure PayPal-hosted page but is embedded on your site using an iFrame.', 'paypal-for-woocommerce'),  
  750. 'options' => array('A' => 'Layout A', 'B' => 'Layout B', 'C' => 'Layout C') 
  751. ),  
  752. 'mobilemode' => array( 
  753. 'title' => __('Mobile Mode', 'paypal-for-woocommerce'),  
  754. 'type' => 'checkbox',  
  755. 'label' => __('Display Mobile optimized form if browsed through Mobile', 'paypal-for-woocommerce'),  
  756. 'default' => 'yes',  
  757. 'description' => sprintf(__('Disable this option if your theme is not compatible with Mobile. Otherwise You would get Silent Post Error in Layout C.', 'paypal-for-woocommerce'), 'https://developer.paypal.com/'),  
  758. ),  
  759. 'card_icon' => array( 
  760. 'title' => __('Credit Card Logo Graphic', 'paypal-for-woocommerce'),  
  761. 'type' => 'text',  
  762. 'default' => plugins_url('/assets/images/cards.png', plugin_basename(dirname(__FILE__))),  
  763. 'class' => 'button_upload' 
  764. ),  
  765. 'invoice_prefix' => array( 
  766. 'title' => __('Invoice Prefix', 'paypal-for-woocommerce'),  
  767. 'type' => 'text',  
  768. 'description' => __('Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number.', 'paypal-for-woocommerce'),  
  769. 'default' => 'WC-PPADV',  
  770. 'desc_tip' => true,  
  771. ),  
  772. 'page_collapse_bgcolor' => array( 
  773. 'title' => __('Page Collapse Border Color', 'paypal-for-woocommerce'),  
  774. 'type' => 'text',  
  775. 'description' => __('Sets the color of the border around the embedded template C.', 'paypal-for-woocommerce'),  
  776. 'default' => '',  
  777. 'desc_tip' => true,  
  778. 'class' => 'paypal_for_woocommerce_color_field' 
  779. ),  
  780. 'page_collapse_textcolor' => array( 
  781. 'title' => __('Page Collapse Text Color', 'paypal-for-woocommerce'),  
  782. 'type' => 'text',  
  783. 'description' => __('Sets the color of the words "Pay with PayPal" and "Pay with credit or debit card".', 'paypal-for-woocommerce'),  
  784. 'default' => '',  
  785. 'desc_tip' => true,  
  786. 'class' => 'paypal_for_woocommerce_color_field' 
  787. ),  
  788. 'page_button_bgcolor' => array( 
  789. 'title' => __('Page Button Background Color', 'paypal-for-woocommerce'),  
  790. 'type' => 'text',  
  791. 'description' => __('Sets the background color of the Pay Now / Submit button.', 'paypal-for-woocommerce'),  
  792. 'default' => '',  
  793. 'desc_tip' => true,  
  794. 'class' => 'paypal_for_woocommerce_color_field' 
  795. ),  
  796. 'page_button_textcolor' => array( 
  797. 'title' => __('Page Button Text Color', 'paypal-for-woocommerce'),  
  798. 'type' => 'text',  
  799. 'description' => __('Sets the color of the text on the Pay Now / Submit button.', 'paypal-for-woocommerce'),  
  800. 'default' => '',  
  801. 'desc_tip' => true,  
  802. 'class' => 'paypal_for_woocommerce_color_field' 
  803. ),  
  804. 'label_textcolor' => array( 
  805. 'title' => __('Label Text Color', 'paypal-for-woocommerce'),  
  806. 'type' => 'text',  
  807. 'description' => __('Sets the color of the text for "card number", "expiration date", ..etc.', 'paypal-for-woocommerce'),  
  808. 'default' => '',  
  809. 'desc_tip' => true,  
  810. 'class' => 'paypal_for_woocommerce_color_field' 
  811. ),  
  812. 'debug' => array( 
  813. 'title' => __('Debug Log', 'paypal-for-woocommerce'),  
  814. 'type' => 'checkbox',  
  815. 'label' => __('Enable logging', 'paypal-for-woocommerce'),  
  816. 'default' => 'no',  
  817. 'description' => sprintf( __( 'Log PayPal events, inside <code>%s</code>', 'paypal-for-woocommerce' ), wc_get_log_file_path( 'paypal_advanced' ) ) 
  818. ),  
  819. 'is_encrypt' => array( 
  820. 'title' => __('', 'paypal-for-woocommerce'),  
  821. 'label' => __('', 'paypal-for-woocommerce'),  
  822. 'type' => 'hidden',  
  823. 'default' => 'yes',  
  824. 'class' => '' 
  825. ); 
  826.  
  827. // End init_form_fields() 
  828.  
  829. /** 
  830. * There are no payment fields for paypal, but we want to show the description if set. 
  831. * @access public 
  832. * @return void 
  833. * */ 
  834. public function payment_fields() { 
  835.  
  836. if ($this->description) { 
  837. echo wpautop(wptexturize($this->description)); 
  838. if ($this->supports('tokenization') && is_checkout()) { 
  839. $this->tokenization_script(); 
  840. $this->saved_payment_methods(); 
  841. $this->save_payment_method_checkbox(); 
  842. do_action('payment_fields_saved_payment_methods', $this); 
  843.  
  844. /** 
  845. * Process the payment 
  846. * @access public 
  847. * @return void 
  848. * */ 
  849. public function process_payment($order_id) { 
  850. $order = new WC_Order($order_id); 
  851. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  852. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  853. if (!empty($_POST['wc-paypal_advanced-new-payment-method']) && $_POST['wc-paypal_advanced-new-payment-method'] == true) { 
  854. if ($old_wc) { 
  855. update_post_meta($order_id, '_is_save_payment_method', 'yes'); 
  856. } else { 
  857. update_post_meta( $order->get_id(), '_is_save_payment_method', 'yes' ); 
  858. if ((!empty($_POST['wc-paypal_advanced-payment-token']) && $_POST['wc-paypal_advanced-payment-token'] != 'new') || !empty($order->subscription_renewal)) { 
  859. if (!empty($order->subscription_renewal)) { 
  860. $payment_tokens_id = get_post_meta($order_id, '_payment_tokens_id', true); 
  861. } else { 
  862. $token_id = wc_clean($_POST['wc-paypal_advanced-payment-token']); 
  863. $token = WC_Payment_Tokens::get($token_id); 
  864. $payment_tokens_id = $token->get_token(); 
  865. $this->create_reference_transaction($payment_tokens_id, $order); 
  866. $inq_result = $this->inquiry_transaction($order, $order_id); 
  867. if ($inq_result == 'Approved') { 
  868. $order->payment_complete($payment_tokens_id); 
  869. $this->save_payment_token($order, $payment_tokens_id); 
  870. if (empty($order->subscription_renewal)) { 
  871. WC()->cart->empty_cart(); 
  872. $order->add_order_note(sprintf(__('Payment completed for the (Order: %s)', 'paypal-for-woocommerce'), $order->get_order_number())); 
  873. if ($this->debug == 'yes') { 
  874. $this->log->add('paypal_advanced', sprintf(__('Payment completed for the (Order: %s)', 'paypal-for-woocommerce'), $order->get_order_number())); 
  875. return array( 
  876. 'result' => 'success',  
  877. 'redirect' => $this->get_return_url($order) 
  878. ); 
  879. //use try/catch blocks to handle exceptions while processing the payment 
  880. try { 
  881.  
  882. //get secure token 
  883. $this->securetoken = $this->get_secure_token($order); 
  884.  
  885. //if valid securetoken 
  886. if ($this->securetoken != "") { 
  887.  
  888. //add token values to post meta and we can use it later 
  889. if ($old_wc) { 
  890. update_post_meta($order_id, '_secure_token_id', $this->secure_token_id); 
  891. update_post_meta($order_id, '_secure_token', $this->securetoken); 
  892. } else { 
  893. update_post_meta( $order->get_id(), '_secure_token_id', $this->secure_token_id ); 
  894. update_post_meta( $order->get_id(), '_secure_token', $this->securetoken ); 
  895.  
  896. //Log 
  897. if ($this->debug == 'yes') 
  898. $this->log->add('paypal_advanced', sprintf(__('Secured Token generated successfully for the order %s', 'paypal-for-woocommerce'), $order->get_order_number())); 
  899.  
  900. //redirect to pay 
  901. return array( 
  902. 'result' => 'success',  
  903. 'redirect' => $order->get_checkout_payment_url(true) 
  904. ); 
  905. } catch (Exception $e) { 
  906.  
  907. //add error 
  908. wc_add_notice(__('Error:', 'paypal-for-woocommerce') . ' "' . $e->getMessage() . '"', 'error'); 
  909.  
  910. //Log 
  911. if ($this->debug == 'yes') 
  912. $this->log->add('paypal_advanced', 'Error Occurred while processing the order ' . $order_id); 
  913. return; 
  914.  
  915. /** 
  916. * Process a refund if supported 
  917. * @param int $order_id 
  918. * @param float $amount 
  919. * @param string $reason 
  920. * @return bool|wp_error True or false based on success, or a WP_Error object 
  921. */ 
  922. public function process_refund($order_id, $amount = null, $reason = '') { 
  923.  
  924. $order = wc_get_order($order_id); 
  925.  
  926. if (!$order || !$order->get_transaction_id()) { 
  927. return false; 
  928.  
  929. if (!is_null($amount) && $order->get_total() > $amount) { 
  930. return new WP_Error('paypal-advanced-error', __('Partial refund is not supported', 'paypal-for-woocommerce')); 
  931.  
  932.  
  933.  
  934. //refund transaction, parameters 
  935. $paypal_args = array( 
  936. 'USER' => $this->user,  
  937. 'VENDOR' => $this->loginid,  
  938. 'PARTNER' => $this->resellerid,  
  939. 'PWD[' . strlen($this->password) . ']' => $this->password,  
  940. 'ORIGID' => $order->get_transaction_id(),  
  941. 'TENDER' => 'C',  
  942. 'TRXTYPE' => 'C',  
  943. 'VERBOSITY' => 'HIGH' 
  944. ); 
  945.  
  946. $postData = ''; //stores the post data string 
  947. foreach ($paypal_args as $key => $val) { 
  948. $postData .= '&' . $key . '=' . $val; 
  949.  
  950. $postData = trim($postData, '&'); 
  951.  
  952. // Using Curl post necessary information to the Paypal Site to generate the secured token 
  953. $response = wp_remote_post($this->hostaddr, array( 
  954. 'method' => 'POST',  
  955. 'body' => $postData,  
  956. 'timeout' => 70,  
  957. 'user-agent' => 'Woocommerce ' . WC_VERSION,  
  958. 'httpversion' => '1.1',  
  959. 'headers' => array('host' => 'www.paypal.com') 
  960. )); 
  961. if (is_wp_error($response)) { 
  962. throw new Exception(__('There was a problem connecting to the payment gateway.', 'paypal-for-woocommerce')); 
  963. if (empty($response['body'])) { 
  964. throw new Exception(__('Empty response.', 'paypal-for-woocommerce')); 
  965. // Parse and assign to array  
  966. $refund_result_arr = array(); //stores the response in array format 
  967. parse_str($response['body'], $refund_result_arr); 
  968.  
  969. //Log 
  970. if ($this->debug == 'yes') { 
  971. $this->log->add('paypal_advanced', sprintf(__('Response of the refund transaction: %s', 'paypal-for-woocommerce'), print_r($refund_result_arr, true))); 
  972.  
  973. if ($refund_result_arr['RESULT'] == 0) { 
  974.  
  975. $order->add_order_note(sprintf(__('Successfully Refunded - Refund Transaction ID: %s', 'paypal-for-woocommerce'), $refund_result_arr['PNREF'])); 
  976. } else { 
  977.  
  978. $order->add_order_note(sprintf(__('Refund Failed - Refund Transaction ID: %s, Error Msg: %s', 'paypal-for-woocommerce'), $refund_result_arr['PNREF'], $refund_result_arr['RESPMSG'])); 
  979. throw new Exception(sprintf(__('Refund Failed - Refund Transaction ID: %s, Error Msg: %s', 'paypal-for-woocommerce'), $refund_result_arr['PNREF'], $refund_result_arr['RESPMSG'])); 
  980.  
  981. return false; 
  982. return true; 
  983.  
  984. /** 
  985. * Displays IFRAME/Redirect to show the hosted page in Paypal 
  986. * @access public 
  987. * @return void 
  988. * */ 
  989. public function receipt_page($order_id) { 
  990.  
  991. //get the mode 
  992. $PF_MODE = $this->testmode == 'yes' ? 'TEST' : 'LIVE'; 
  993. //create order object 
  994. $order = new WC_Order($order_id); 
  995.  
  996. //get the tokens 
  997. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  998. $this->secure_token_id = $old_wc ? get_post_meta($order->id, '_secure_token_id', true) : get_post_meta($order->get_id(), '_secure_token_id', true); 
  999. $this->securetoken = $old_wc ? get_post_meta($order->id, '_secure_token', true) : get_post_meta($order->get_id(), '_secure_token', true); 
  1000.  
  1001. //Log the browser and its version 
  1002. if ($this->debug == 'yes') 
  1003. $this->log->add('paypal_advanced', sprintf(__('Browser Info: %s', 'paypal-for-woocommerce'), $_SERVER['HTTP_USER_AGENT'])); 
  1004.  
  1005. //display the form in IFRAME, if it is layout C, otherwise redirect to paypal site 
  1006. if ($this->layout == 'MINLAYOUT' || $this->layout == 'C') { 
  1007. //define the url 
  1008. $location = 'https://payflowlink.paypal.com?mode=' . $PF_MODE . '&SECURETOKEN=' . $this->securetoken . '&SECURETOKENID=' . $this->secure_token_id; 
  1009. $this->add_log(sprintf(__('Show payment form(IFRAME) for the order %s as it is configured to use Layout C', 'paypal-for-woocommerce'), $order->get_order_number())); 
  1010. //display the form 
  1011. ?> 
  1012. <iframe id="paypal_for_woocommerce_iframe" src="<?php echo $location; ?>" width="550" height="565" scrolling="no" frameborder="0" border="0" allowtransparency="true"></iframe> 
  1013.  
  1014. <?php 
  1015. } else { 
  1016. //define the redirection url 
  1017. $this->add_log(sprintf(__('Show payment form redirecting to ' . $location . ' for the order %s as it is not configured to use Layout C', 'paypal-for-woocommerce'), $order->get_order_number())); 
  1018. $location = 'https://payflowlink.paypal.com?mode=' . $PF_MODE . '&SECURETOKEN=' . $this->securetoken . '&SECURETOKENID=' . $this->secure_token_id; 
  1019.  
  1020. //Log 
  1021. if ($this->debug == 'yes') 
  1022. $this->log->add('paypal_advanced', sprintf(__('Show payment form redirecting to ' . $location . ' for the order %s as it is not configured to use Layout C', 'paypal-for-woocommerce'), $order->get_order_number())); 
  1023.  
  1024. //redirect 
  1025. wp_redirect($location); 
  1026. exit; 
  1027.  
  1028. /** 
  1029. * Limit the length of item names 
  1030. * @param string $item_name 
  1031. * @return string 
  1032. */ 
  1033. public function paypal_advanced_item_name($item_name) { 
  1034. if (strlen($item_name) > 36) { 
  1035. $item_name = substr($item_name, 0, 33) . '...'; 
  1036. return html_entity_decode($item_name, ENT_NOQUOTES, 'UTF-8'); 
  1037.  
  1038. /** 
  1039. * Limit the length of item desc 
  1040. * @param string $item_desc 
  1041. * @return string 
  1042. */ 
  1043. public function paypal_advanced_item_desc($item_desc) { 
  1044. if (strlen($item_desc) > 127) { 
  1045. $item_desc = substr($item_desc, 0, 124) . '...'; 
  1046. return html_entity_decode($item_desc, ENT_NOQUOTES, 'UTF-8'); 
  1047.  
  1048. public function create_reference_transaction($token, $order) { 
  1049. static $length_error = 0; 
  1050. $shipping_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(); 
  1051. $shipping_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(); 
  1052. $shipping_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(); 
  1053. $shipping_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(); 
  1054. $shiptostreet = $shipping_address_1 . ' ' . $shipping_address_2; 
  1055. $shipping_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(); 
  1056. $shipping_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(); 
  1057. $shipping_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(); 
  1058. $shipping_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(); 
  1059. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  1060.  
  1061. $billing_company = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(); 
  1062. $billing_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  1063. $billing_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  1064. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  1065. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  1066. $billtostreet = $billing_address_1 . ' ' . $billing_address_2; 
  1067. $billing_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_city : $order->get_billing_city(); 
  1068. $billing_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_postcode : $order->get_billing_postcode(); 
  1069. $billing_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_country : $order->get_billing_country(); 
  1070. $billing_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_state : $order->get_billing_state(); 
  1071. $billing_email = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_email : $order->get_billing_email(); 
  1072. $billing_phone = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_phone : $order->get_billing_phone(); 
  1073.  
  1074. $this->transtype = ($order->get_total() == 0 ) ? 'A' : $this->transtype; 
  1075.  
  1076. $paypal_args = array(); 
  1077. $paypal_args = array( 
  1078. 'VERBOSITY' => 'HIGH',  
  1079. 'TENDER' => 'C',  
  1080. 'ORIGID' => $token,  
  1081. 'USER' => $this->user,  
  1082. 'VENDOR' => $this->loginid,  
  1083. 'PARTNER' => $this->resellerid,  
  1084. 'PWD[' . strlen($this->password) . ']' => $this->password,  
  1085. 'TRXTYPE' => $this->transtype,  
  1086. 'CUSTREF' => $order->get_order_number(),  
  1087. 'USER1' => $order_id,  
  1088. 'INVNUM' => $this->invoice_id_prefix . preg_replace("/[^a-zA-Z0-9]/", "", str_replace("#", "", $order->get_order_number())),  
  1089. 'AMT' => number_format($order->get_total(), 2, '.', ''),  
  1090. 'FREIGHTAMT' => '',  
  1091. 'COMPANYNAME[' . strlen($billing_company) . ']' => $billing_company,  
  1092. 'CURRENCY' => version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency(),  
  1093. 'EMAIL' => $billing_email,  
  1094. 'BILLTOFIRSTNAME[' . strlen($billing_first_name) . ']' => $billing_first_name,  
  1095. 'BILLTOLASTNAME[' . strlen($billing_last_name) . ']' => $billing_last_name,  
  1096. 'BILLTOSTREET[' . strlen($billtostreet) . ']' => $billtostreet,  
  1097. 'BILLTOCITY[' . strlen($billing_city) . ']' => $billing_city,  
  1098. 'BILLTOSTATE[' . strlen($billing_state) . ']' => $billing_state,  
  1099. 'BILLTOZIP' => $billing_postcode,  
  1100. 'BILLTOCOUNTRY[' . strlen($billing_country) . ']' => $billing_country,  
  1101. 'BILLTOEMAIL' => $billing_email,  
  1102. 'BILLTOPHONENUM' => $billing_phone,  
  1103. 'SHIPTOFIRSTNAME[' . strlen($shipping_first_name) . ']' => $shipping_first_name,  
  1104. 'SHIPTOLASTNAME[' . strlen($shipping_last_name) . ']' => $shipping_last_name,  
  1105. 'SHIPTOSTREET[' . strlen($shiptostreet) . ']' => $shiptostreet,  
  1106. 'SHIPTOCITY[' . strlen($shipping_city) . ']' => $shipping_city,  
  1107. 'SHIPTOZIP' => $shipping_postcode,  
  1108. 'SHIPTOCOUNTRY[' . strlen($shipping_country) . ']' => $shipping_country,  
  1109. 'BUTTONSOURCE' => 'AngellEYE_SP_WooCommerce',  
  1110. 'MERCHDESCR' => $this->softdescriptor 
  1111. ); 
  1112. if (!empty($order->subscription_renewal)) { 
  1113. $paypal_args['origid'] = get_post_meta($order_id, '_payment_tokens_id', true); 
  1114. if (empty($shipping_state)) { 
  1115. $paypal_args['SHIPTOSTATE[' . strlen($shipping_state) . ']'] = $shipping_state; 
  1116. } else { 
  1117. $paypal_args['SHIPTOSTATE[' . strlen($shipping_state) . ']'] = $shipping_state; 
  1118. $is_prices_include_tax = version_compare(WC_VERSION, '3.0', '<') ? 'yes' === $order->prices_include_tax : $order->get_prices_include_tax(); 
  1119. if (($is_prices_include_tax || $order->get_total_discount() > 0 || $length_error > 1) && $order->get_subtotal() > 0) { 
  1120. $item_names = array(); 
  1121. if (sizeof($order->get_items()) > 0) { 
  1122. if ($length_error <= 1) { 
  1123. foreach ($order->get_items() as $item) { 
  1124. if ($item['qty']) { 
  1125. $item_names[] = $item['name'] . ' x ' . $item['qty']; 
  1126. } else { 
  1127. $item_names[] = "All selected items, refer to Woocommerce order details"; 
  1128. $items_str = sprintf(__('Order %s', 'paypal-for-woocommerce'), $order->get_order_number()) . " - " . implode(', ', $item_names); 
  1129. $items_names_str = $this->paypal_advanced_item_name($items_str); 
  1130. $items_desc_str = $this->paypal_advanced_item_desc($items_str); 
  1131. $paypal_args['L_NAME0[' . strlen($items_names_str) . ']'] = $items_names_str; 
  1132. $paypal_args['L_DESC0[' . strlen($items_desc_str) . ']'] = $items_desc_str; 
  1133. $paypal_args['L_QTY0'] = 1; 
  1134. if ($order->get_subtotal() == 0) { 
  1135. $paypal_args['L_COST0'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  1136. } else { 
  1137. $paypal_args['FREIGHTAMT'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  1138. $paypal_args['L_COST0'] = number_format($order->get_total() - round(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2), 2, '.', ''); 
  1139. $paypal_args['ITEMAMT'] = $paypal_args['L_COST0'] * $paypal_args['L_QTY0']; 
  1140. } else { 
  1141. $paypal_args['TAXAMT'] = $order->get_total_tax(); 
  1142. $paypal_args['ITEMAMT'] = 0; 
  1143. $item_loop = 0; 
  1144. if (sizeof($order->get_items()) > 0 && $order->get_subtotal() > 0) { 
  1145. foreach ($order->get_items() as $item) { 
  1146. if ($item['qty']) { 
  1147. $product = $order->get_product_from_item($item); 
  1148. $item_name = $item['name']; 
  1149. $item_meta = new WC_order_item_meta($item['item_meta']); 
  1150. if ($length_error == 0 && $meta = $item_meta->display(true, true)) { 
  1151. $item_name .= ' (' . $meta . ')'; 
  1152. $item_name = $this->paypal_advanced_item_name($item_name); 
  1153. $paypal_args['L_NAME' . $item_loop . '[' . strlen($item_name) . ']'] = $item_name; 
  1154. if ($product->get_sku()) { 
  1155. $paypal_args['L_SKU' . $item_loop] = $product->get_sku(); 
  1156. $paypal_args['L_QTY' . $item_loop] = $item['qty']; 
  1157. $paypal_args['L_COST' . $item_loop] = $order->get_item_total($item, false, false); /** No Tax , No Round) */ 
  1158. $paypal_args['L_TAXAMT' . $item_loop] = $order->get_item_tax($item, false); /** No Round it */ 
  1159. $paypal_args['ITEMAMT'] += $order->get_line_total($item, false, false); /** No tax, No Round */ 
  1160. $item_loop++; 
  1161. } else { 
  1162. $paypal_args['L_NAME0'] = sprintf(__('Shipping via %s', 'woocommerce'), $order->get_shipping_method()); 
  1163. $paypal_args['L_QTY0'] = 1; 
  1164. $paypal_args['L_COST0'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  1165. $paypal_args['ITEMAMT'] = number_format(version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_total_shipping() : $order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', ''); 
  1166. try { 
  1167. $postData = ''; 
  1168. $logData = ''; 
  1169. foreach ($paypal_args as $key => $val) { 
  1170. $postData .= '&' . $key . '=' . $val; 
  1171. if (strpos($key, 'PWD') === 0) { 
  1172. $logData .= '&PWD=XXXX'; 
  1173. } else { 
  1174. $logData .= '&' . $key . '=' . $val; 
  1175. $postData = trim($postData, '&'); 
  1176. $response = wp_remote_post($this->hostaddr, array( 
  1177. 'method' => 'POST',  
  1178. 'body' => apply_filters('angelleye_woocommerce_paypal_advanced_create_reference_transaction_request_args', $postData),  
  1179. 'timeout' => 70,  
  1180. 'user-agent' => 'WooCommerce ' . WC_VERSION,  
  1181. 'httpversion' => '1.1',  
  1182. 'headers' => array('host' => 'www.paypal.com') 
  1183. )); 
  1184. if (is_wp_error($response)) { 
  1185. throw new Exception($response->get_error_message()); 
  1186. if (empty($response['body'])) { 
  1187. throw new Exception(__('Empty response.', 'paypal-for-woocommerce')); 
  1188. parse_str($response['body'], $arr); 
  1189. if ($arr['RESULT'] > 0) { 
  1190. throw new Exception(__('There was an error processing your order - ' . $arr['RESPMSG'], 'paypal-for-woocommerce')); 
  1191. } else {//return the secure token 
  1192. $_POST['PNREF'] = $arr['PNREF']; 
  1193. return $arr['RESPMSG']; 
  1194. } catch (Exception $e) { 
  1195.  
  1196. if ($arr['RESULT'] != 7) { 
  1197. wc_add_notice(__('Error:', 'paypal-for-woocommerce') . ' "' . $e->getMessage() . '"', 'error'); 
  1198. $length_error = 0; 
  1199. return; 
  1200. } else { 
  1201. $length_error++; 
  1202.  
  1203. public function add_log($message) { 
  1204. if ($this->debug) { 
  1205. if (!isset($this->log)) { 
  1206. $this->log = new WC_Logger(); 
  1207. $this->log->add($this->id, $message); 
  1208.  
  1209. public function are_reference_transactions_enabled($token_id) { 
  1210. if ($this->supports('tokenization') && class_exists('WC_Subscriptions_Order')) { 
  1211. $are_reference_transactions_enabled = get_option('are_reference_transactions_enabled', 'no'); 
  1212. if ($are_reference_transactions_enabled == 'no') { 
  1213. $customer_id = get_current_user_id(); 
  1214. if (!class_exists('Angelleye_PayPal')) { 
  1215. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  1216. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  1217. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  1218. $PayPalConfig = array( 
  1219. 'Sandbox' => $this->testmode,  
  1220. 'APIUsername' => $this->paypal_user,  
  1221. 'APIPassword' => trim($this->paypal_password),  
  1222. 'APIVendor' => $this->paypal_vendor,  
  1223. 'APIPartner' => $this->paypal_partner,  
  1224. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  1225. ); 
  1226. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  1227. $this->validate_fields(); 
  1228. $card = $this->get_posted_card(); 
  1229. $billtofirstname = (get_user_meta($customer_id, 'billing_first_name', true)) ? get_user_meta($customer_id, 'billing_first_name', true) : get_user_meta($customer_id, 'shipping_first_name', true); 
  1230. $billtolastname = (get_user_meta($customer_id, 'billing_last_name', true)) ? get_user_meta($customer_id, 'billing_last_name', true) : get_user_meta($customer_id, 'shipping_last_name', true); 
  1231. $billtostate = (get_user_meta($customer_id, 'billing_state', true)) ? get_user_meta($customer_id, 'billing_state', true) : get_user_meta($customer_id, 'shipping_state', true); 
  1232. $billtocountry = (get_user_meta($customer_id, 'billing_country', true)) ? get_user_meta($customer_id, 'billing_country', true) : get_user_meta($customer_id, 'shipping_country', true); 
  1233. $billtozip = (get_user_meta($customer_id, 'billing_postcode', true)) ? get_user_meta($customer_id, 'billing_postcode', true) : get_user_meta($customer_id, 'shipping_postcode', true); 
  1234. $PayPalRequestData = array( 
  1235. 'tender' => 'C',  
  1236. 'trxtype' => 'A',  
  1237. 'acct' => '',  
  1238. 'expdate' => '',  
  1239. 'amt' => '0.00',  
  1240. 'currency' => get_woocommerce_currency(),  
  1241. 'cvv2' => '',  
  1242. 'orderid' => '',  
  1243. 'orderdesc' => '',  
  1244. 'billtoemail' => '',  
  1245. 'billtophonenum' => '',  
  1246. 'billtofirstname' => $billtofirstname,  
  1247. 'billtomiddlename' => '',  
  1248. 'billtolastname' => $billtolastname,  
  1249. 'billtostreet' => '',  
  1250. 'billtocity' => '',  
  1251. 'billtostate' => $billtostate,  
  1252. 'billtozip' => $billtozip,  
  1253. 'billtocountry' => $billtocountry,  
  1254. 'origid' => $token_id,  
  1255. 'custref' => '',  
  1256. 'custcode' => '',  
  1257. 'custip' => $this->get_user_ip(),  
  1258. 'invnum' => '',  
  1259. 'ponum' => '',  
  1260. 'starttime' => '',  
  1261. 'endtime' => '',  
  1262. 'securetoken' => '',  
  1263. 'partialauth' => '',  
  1264. 'authcode' => '' 
  1265. ); 
  1266. $PayPalResult = $PayPal->ProcessTransaction($PayPalRequestData); 
  1267. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 117)) { 
  1268. $admin_email = get_option("admin_email"); 
  1269. $message = __("PayPal Reference Transactions are not enabled on your account, some subscription management features are not enabled", "paypal-for-woocommerce") . "\n\n"; 
  1270. $message .= __("PayFlow API call failed.", "paypal-for-woocommerce") . "\n\n"; 
  1271. $message .= __('Error Code: ', 'paypal-for-woocommerce') . $PayPalResult['RESULT'] . "\n"; 
  1272. $message .= __('Detailed Error Message: ', 'paypal-for-woocommerce') . $PayPalResult['RESPMSG']; 
  1273. $message .= isset($PayPalResult['PREFPSMSG']) && $PayPalResult['PREFPSMSG'] != '' ? ' - ' . $PayPalResult['PREFPSMSG'] . "\n" : "\n"; 
  1274. $message .= __('User IP: ', 'paypal-for-woocommerce') . $this->get_user_ip() . "\n"; 
  1275. $message = apply_filters('ae_pppf_error_email_message', $message); 
  1276. $subject = apply_filters('ae_pppf_error_email_subject', "PayPal Payments Pro (PayFlow) Error Notification"); 
  1277. wp_mail($admin_email, $subject, $message); 
  1278. return false; 
  1279. } else { 
  1280. update_option('are_reference_transactions_enabled', 'yes'); 
  1281.  
  1282. public function send_failed_order_email($order_id) { 
  1283. $emails = WC()->mailer()->get_emails(); 
  1284. if (!empty($emails) && !empty($order_id)) { 
  1285. $emails['WC_Email_Failed_Order']->trigger($order_id); 
  1286.  
  1287. public function save_payment_token($order, $payment_tokens_id) { 
  1288. // Store source in the order 
  1289. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  1290. if (!empty($payment_tokens_id)) { 
  1291. update_post_meta($order_id, '_payment_tokens_id', $payment_tokens_id); 
  1292.  
  1293. public function angelleye_paypal_advanced_encrypt_gateway_api($settings) { 
  1294. if( !empty($settings['resellerid'])) { 
  1295. $resellerid = $settings['resellerid']; 
  1296. }  
  1297. if(strlen($resellerid) > 28 ) { 
  1298. return $settings; 
  1299. if( !empty($settings['is_encrypt']) ) { 
  1300. $gateway_settings_keys = array('loginid', 'resellerid', 'user', 'password'); 
  1301. foreach ($gateway_settings_keys as $gateway_settings_key => $gateway_settings_value) { 
  1302. if( !empty( $settings[$gateway_settings_value]) ) { 
  1303. $settings[$gateway_settings_value] = AngellEYE_Utility::crypting($settings[$gateway_settings_value], $action = 'e'); 
  1304. return $settings; 
  1305.