WC_Gateway_Braintree_AngellEYE

WC_Gateway_Braintree_AngellEYE class.

Defined (1)

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

/classes/wc-gateway-braintree-angelleye.php  
  1. class WC_Gateway_Braintree_AngellEYE extends WC_Payment_Gateway_CC { 
  2.  
  3. /** 
  4. * Constructor 
  5. */ 
  6. public $customer_id; 
  7.  
  8. function __construct() { 
  9. $this->id = 'braintree'; 
  10. $this->icon = $this->get_option('card_icon', plugins_url('/assets/images/cards.png', plugin_basename(dirname(__FILE__)))); 
  11. if (is_ssl()) { 
  12. $this->icon = preg_replace("/^http:/i", "https:", $this->icon); 
  13. $this->icon = apply_filters('woocommerce_braintree_icon', $this->icon); 
  14. $this->has_fields = true; 
  15. $this->method_title = 'Braintree'; 
  16. $this->method_description = __('Credit Card payments Powered by PayPal / Braintree.', 'paypal-for-woocommerce'); 
  17. $this->supports = array( 
  18. 'products',  
  19. 'refunds' 
  20. ); 
  21. $this->init_form_fields(); 
  22. $this->init_settings(); 
  23. $this->enable_tokenized_payments = $this->get_option('enable_tokenized_payments', 'no'); 
  24. if ($this->enable_tokenized_payments == 'yes') { 
  25. $this->supports = array( 
  26. 'subscriptions',  
  27. 'products',  
  28. 'refunds',  
  29. 'subscription_cancellation',  
  30. 'subscription_reactivation',  
  31. 'subscription_suspension',  
  32. 'subscription_amount_changes',  
  33. 'subscription_payment_method_change', // Subs 1.n compatibility. 
  34. 'subscription_payment_method_change_customer',  
  35. 'subscription_payment_method_change_admin',  
  36. 'subscription_date_changes',  
  37. 'multiple_subscriptions',  
  38. 'add_payment_method',  
  39. 'tokenization' 
  40. ); 
  41. $this->title = $this->get_option('title'); 
  42. $this->description = $this->get_option('description'); 
  43. $this->enabled = $this->get_option('enabled'); 
  44. $this->sandbox = 'yes' === $this->get_option('sandbox', 'yes'); 
  45. if ($this->sandbox == false) { 
  46. $this->sandbox = AngellEYE_Utility::angelleye_paypal_for_woocommerce_is_set_sandbox_product(); 
  47. $this->environment = $this->sandbox == false ? 'production' : 'sandbox'; 
  48. $this->merchant_id = $this->sandbox == false ? $this->get_option('merchant_id') : $this->get_option('sandbox_merchant_id'); 
  49. $this->private_key = $this->sandbox == false ? $this->get_option('private_key') : $this->get_option('sandbox_private_key'); 
  50. $this->public_key = $this->sandbox == false ? $this->get_option('public_key') : $this->get_option('sandbox_public_key'); 
  51. $this->enable_braintree_drop_in = $this->get_option('enable_braintree_drop_in') === "yes" ? true : false; 
  52. $this->merchant_account_id = $this->sandbox == false ? $this->get_option('merchant_account_id') : $this->get_option('sandbox_merchant_account_id'); 
  53. $this->debug = 'yes' === $this->get_option('debug', 'no'); 
  54. $this->is_encrypt = $this->get_option('is_encrypt', 'no'); 
  55. $this->softdescriptor = $this->get_option('softdescriptor', ''); 
  56. add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); 
  57. add_filter('woocommerce_settings_api_sanitized_fields_' . $this->id, array($this, 'angelleye_braintree_encrypt_gateway_api'), 10, 1); 
  58. $this->response = ''; 
  59. if ($this->enable_braintree_drop_in) { 
  60. add_action('wp_enqueue_scripts', array($this, 'payment_scripts'), 0); 
  61. add_action('admin_notices', array($this, 'checks')); 
  62. add_filter('woocommerce_credit_card_form_fields', array($this, 'angelleye_braintree_credit_card_form_fields'), 10, 2); 
  63. $this->customer_id; 
  64.  
  65. /** 
  66. * Admin Panel Options 
  67. */ 
  68. public function admin_options() { 
  69. ?> 
  70. <h3><?php _e('Braintree', 'paypal-for-woocommerce'); ?></h3> 
  71. <p><?php _e($this->method_description, 'paypal-for-woocommerce'); ?></p> 
  72. <table class="form-table"> 
  73. <?php $this->generate_settings_html(); ?> 
  74. <script type="text/javascript"> 
  75. jQuery('#woocommerce_braintree_sandbox').change(function () { 
  76. sandbox = jQuery('#woocommerce_braintree_sandbox_public_key, #woocommerce_braintree_sandbox_private_key, #woocommerce_braintree_sandbox_merchant_id, #woocommerce_braintree_sandbox_merchant_account_id').closest('tr'),  
  77. production = jQuery('#woocommerce_braintree_public_key, #woocommerce_braintree_private_key, #woocommerce_braintree_merchant_id, #woocommerce_braintree_merchant_account_id').closest('tr'); 
  78. if (jQuery(this).is(':checked')) { 
  79. sandbox.show(); 
  80. production.hide(); 
  81. } else { 
  82. sandbox.hide(); 
  83. production.show(); 
  84. }).change(); 
  85. </script> 
  86. </table> <?php 
  87.  
  88. /** 
  89. * Check if SSL is enabled and notify the user 
  90. */ 
  91. public function checks() { 
  92. if ($this->enabled == 'no') { 
  93. return; 
  94. if (version_compare(phpversion(), '5.2.1', '<')) { 
  95. echo '<div class="error"><p>' . sprintf(__('Braintree Error: Braintree requires PHP 5.2.1 and above. You are using version %s.', 'paypal-for-woocommerce'), phpversion()) . '</p></div>'; 
  96. if ('no' == get_option('woocommerce_force_ssl_checkout') && !class_exists('WordPressHTTPS') && $this->enable_braintree_drop_in == false && $this->sandbox == false) { 
  97. echo '<div class="error"><p>' . sprintf(__('Braintree is enabled, but the <a href="%s">force SSL option</a> is disabled; your checkout may not be secure! Please enable SSL and ensure your server has a valid SSL certificate - Braintree custome credit card UI will only work in sandbox mode.', 'paypal-for-woocommerce'), admin_url('admin.php?page=wc-settings&tab=checkout')) . '</p></div>'; 
  98. $this->add_dependencies_admin_notices(); 
  99.  
  100. /** 
  101. * Check if this gateway is enabled 
  102. */ 
  103. public function is_available() { 
  104. if ('yes' != $this->enabled) { 
  105. return false; 
  106. if (!$this->merchant_id || !$this->public_key || !$this->private_key) { 
  107. return false; 
  108. return true; 
  109.  
  110. public function validate_fields() { 
  111. if (!$this->enable_braintree_drop_in) { 
  112. try { 
  113. if (isset($_POST['wc-braintree-payment-token']) && 'new' !== $_POST['wc-braintree-payment-token']) { 
  114. $token_id = wc_clean($_POST['wc-braintree-payment-token']); 
  115. $token = WC_Payment_Tokens::get($token_id); 
  116. if ($token->get_user_id() !== get_current_user_id()) { 
  117. throw new Exception(__('Error processing checkout. Please try again.', 'paypal-for-woocommerce')); 
  118. } else { 
  119. return true; 
  120. } else { 
  121. $card = $this->get_posted_card(); 
  122. if (empty($card->exp_month) || empty($card->exp_year)) { 
  123. throw new Exception(__('Card expiration date is invalid', 'paypal-for-woocommerce')); 
  124. if (!ctype_digit($card->cvc)) { 
  125. throw new Exception(__('Card security code is invalid (only digits are allowed)', 'paypal-for-woocommerce')); 
  126. if (!ctype_digit($card->exp_month) || !ctype_digit($card->exp_year) || $card->exp_month > 12 || $card->exp_month < 1 || $card->exp_year < date('y')) { 
  127. throw new Exception(__('Card expiration date is invalid', 'paypal-for-woocommerce')); 
  128. if (empty($card->number) || !ctype_digit($card->number)) { 
  129. throw new Exception(__('Card number is invalid', 'paypal-for-woocommerce')); 
  130. return true; 
  131. } catch (Exception $e) { 
  132. wc_add_notice($e->getMessage(), 'error'); 
  133. return false; 
  134. return true; 
  135. } else { 
  136. try { 
  137. if (isset($_POST['braintree_token']) && !empty($_POST['braintree_token'])) { 
  138. return true; 
  139. } else { 
  140. throw new Exception(__('Braintree payment method nonce is empty', 'paypal-for-woocommerce')); 
  141. } catch (Exception $e) { 
  142. wc_add_notice($e->getMessage(), 'error'); 
  143. return false; 
  144. return true; 
  145.  
  146. /** 
  147. * Initialise Gateway Settings Form Fields 
  148. */ 
  149. public function init_form_fields() { 
  150. $this->form_fields = array( 
  151. 'enabled' => array( 
  152. 'title' => __('Enable/Disable', 'paypal-for-woocommerce'),  
  153. 'label' => __('Enable Braintree Payment Gateway', 'paypal-for-woocommerce'),  
  154. 'type' => 'checkbox',  
  155. 'description' => '',  
  156. 'default' => 'no' 
  157. ),  
  158. 'title' => array( 
  159. 'title' => __('Title', 'paypal-for-woocommerce'),  
  160. 'type' => 'text',  
  161. 'description' => __('This controls the title which the user sees during checkout.', 'paypal-for-woocommerce'),  
  162. 'default' => __('Credit Card', 'paypal-for-woocommerce'),  
  163. 'desc_tip' => true 
  164. ),  
  165. 'description' => array( 
  166. 'title' => __('Description', 'paypal-for-woocommerce'),  
  167. 'type' => 'textarea',  
  168. 'description' => __('This controls the description which the user sees during checkout.', 'paypal-for-woocommerce'),  
  169. 'default' => 'Pay securely with your credit card.',  
  170. 'desc_tip' => true 
  171. ),  
  172. 'enable_braintree_drop_in' => array( 
  173. 'title' => __('Enable Drop-in Payment UI', 'paypal-for-woocommerce'),  
  174. 'label' => __('Enable Drop-in Payment UI', 'paypal-for-woocommerce'),  
  175. 'type' => 'checkbox',  
  176. 'description' => __('Rather than showing a credit card form on your checkout, this shows the form on it\'s own page, thus making the process more secure and more PCI friendly.', 'paypal-for-woocommerce'),  
  177. 'default' => 'yes' 
  178. ),  
  179. 'sandbox' => array( 
  180. 'title' => __('Sandbox', 'paypal-for-woocommerce'),  
  181. 'label' => __('Enable Sandbox Mode', 'paypal-for-woocommerce'),  
  182. 'type' => 'checkbox',  
  183. 'description' => __('Place the payment gateway in sandbox mode using sandbox API keys (real payments will not be taken).', 'paypal-for-woocommerce'),  
  184. 'default' => 'yes' 
  185. ),  
  186. 'sandbox_public_key' => array( 
  187. 'title' => __('Sandbox Public Key', 'paypal-for-woocommerce'),  
  188. 'type' => 'password',  
  189. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  190. 'default' => '',  
  191. 'desc_tip' => true 
  192. ),  
  193. 'sandbox_private_key' => array( 
  194. 'title' => __('Sandbox Private Key', 'paypal-for-woocommerce'),  
  195. 'type' => 'password',  
  196. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  197. 'default' => '',  
  198. 'desc_tip' => true 
  199. ),  
  200. 'sandbox_merchant_id' => array( 
  201. 'title' => __('Sandbox Merchant ID', 'paypal-for-woocommerce'),  
  202. 'type' => 'password',  
  203. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  204. 'default' => '',  
  205. 'desc_tip' => true 
  206. ),  
  207. 'sandbox_merchant_account_id' => array( 
  208. 'type' => 'text',  
  209. 'default' => '',  
  210. 'title' => __('Sandbox Merchant Account Id', 'paypal-for-woocommerce'),  
  211. 'tool_tip' => true,  
  212. 'description' => __('NOTE: Not to be confused with the API key Merchant ID. The Merchant Account ID determines the currency that the payment is settled in. You can find your Merchant Account Id by logging into Braintree,  
  213. and clicking Settings > Processing and scrolling to the bottom of the page.', 'paypal-for-woocommerce') 
  214. ),  
  215. 'public_key' => array( 
  216. 'title' => __('Live Public Key', 'paypal-for-woocommerce'),  
  217. 'type' => 'password',  
  218. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  219. 'default' => '',  
  220. 'desc_tip' => true 
  221. ),  
  222. 'private_key' => array( 
  223. 'title' => __('Live Private Key', 'paypal-for-woocommerce'),  
  224. 'type' => 'password',  
  225. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  226. 'default' => '',  
  227. 'desc_tip' => true 
  228. ),  
  229. 'merchant_id' => array( 
  230. 'title' => __('Live Merchant ID', 'paypal-for-woocommerce'),  
  231. 'type' => 'password',  
  232. 'description' => __('Get your API keys from your Braintree account.', 'paypal-for-woocommerce'),  
  233. 'default' => '',  
  234. 'desc_tip' => true 
  235. ),  
  236. 'merchant_account_id' => array( 
  237. 'type' => 'text',  
  238. 'default' => '',  
  239. 'title' => __('Live Merchant Account Id', 'paypal-for-woocommerce'),  
  240. 'tool_tip' => true,  
  241. 'description' => __('NOTE: Not to be confused with the API key Merchant ID. The Merchant Account ID determines the currency that the payment is settled in. You can find your Merchant Account Id by logging into Braintree,  
  242. and clicking Settings > Processing and scrolling to the bottom of the page.', 'paypal-for-woocommerce') 
  243. ),  
  244. 'enable_tokenized_payments' => array( 
  245. 'title' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  246. 'label' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  247. 'type' => 'checkbox',  
  248. 'description' => __('Allow buyers to securely save payment details to their account for quick checkout / auto-ship orders in the future.', 'paypal-for-woocommerce'),  
  249. 'default' => 'no',  
  250. 'class' => 'enable_tokenized_payments' 
  251. ),  
  252. 'softdescriptor' => array( 
  253. 'title' => __('Credit Card Statement Name', 'paypal-for-woocommerce'),  
  254. 'type' => 'text',  
  255. 'description' => __('The value entered here will be displayed on the buyer\'s credit card statement.', 'paypal-for-woocommerce'),  
  256. 'default' => '',  
  257. 'desc_tip' => true,  
  258. ),  
  259. 'card_icon' => array( 
  260. 'title' => __('Card Icon', 'paypal-for-woocommerce'),  
  261. 'type' => 'text',  
  262. 'default' => plugins_url('/assets/images/cards.png', plugin_basename(dirname(__FILE__))),  
  263. 'class' => 'button_upload' 
  264. ),  
  265. 'debug' => array( 
  266. 'title' => __('Debug Log', 'paypal-for-woocommerce'),  
  267. 'type' => 'checkbox',  
  268. 'label' => __('Enable logging', 'paypal-for-woocommerce'),  
  269. 'default' => 'no',  
  270. 'description' => sprintf( __( 'Log PayPal/Braintree events, inside <code>%s</code>', 'paypal-for-woocommerce' ), wc_get_log_file_path( 'braintree' ) ) 
  271. ),  
  272. 'is_encrypt' => array( 
  273. 'title' => __('', 'paypal-for-woocommerce'),  
  274. 'label' => __('', 'paypal-for-woocommerce'),  
  275. 'type' => 'hidden',  
  276. 'default' => 'yes',  
  277. 'class' => '' 
  278. ); 
  279.  
  280. public function payment_fields() { 
  281. global $woocommerce; 
  282. if ($this->description) { 
  283. echo wpautop(wptexturize($this->description)); 
  284. $this->tokenization_script(); 
  285. if ($this->enable_braintree_drop_in) { 
  286. $this->angelleye_braintree_lib(); 
  287. $this->add_log('Begin Braintree_ClientToken::generate Request'); 
  288. try { 
  289. if (is_user_logged_in()) { 
  290. $customer_id = get_current_user_id(); 
  291. $braintree_customer_id = get_user_meta($customer_id, 'braintree_customer_id', true); 
  292. if (!empty($braintree_customer_id) && !empty($this->merchant_account_id)) { 
  293. $clientToken = Braintree_ClientToken::generate(array('customerId' => $braintree_customer_id, 'merchantAccountId' => $this->merchant_account_id)); 
  294. } else if (!empty($braintree_customer_id)) { 
  295. $clientToken = Braintree_ClientToken::generate(array('customerId' => $braintree_customer_id)); 
  296. } else { 
  297. $clientToken = Braintree_ClientToken::generate(); 
  298. } else { 
  299. $clientToken = Braintree_ClientToken::generate(); 
  300. } catch (Braintree_Exception_Authentication $e) { 
  301. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  302. $this->add_log("Braintree_ClientToken::generate Exception: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  303. wp_redirect($woocommerce->cart->get_cart_url()); 
  304. exit; 
  305. } catch (Braintree_Exception_Authorization $e) { 
  306. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  307. $this->add_log("Braintree_ClientToken::generate Exception: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  308. wp_redirect($woocommerce->cart->get_cart_url()); 
  309. exit; 
  310. } catch (Braintree_Exception_DownForMaintenance $e) { 
  311. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  312. $this->add_log("Braintree_ClientToken::generate Exception: Request times out."); 
  313. wp_redirect($woocommerce->cart->get_cart_url()); 
  314. exit; 
  315. } catch (Braintree_Exception_ServerError $e) { 
  316. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  317. $this->add_log("Braintree_ClientToken::generate Braintree_Exception_ServerError" . $e->getMessage()); 
  318. wp_redirect($woocommerce->cart->get_cart_url()); 
  319. exit; 
  320. } catch (Braintree_Exception_SSLCertificate $e) { 
  321. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  322. $this->add_log("Braintree_ClientToken::generate Braintree_Exception_SSLCertificate" . $e->getMessage()); 
  323. wp_redirect($woocommerce->cart->get_cart_url()); 
  324. exit; 
  325. } catch (InvalidArgumentException $e) { 
  326. if ($e->getMessage() == 'Customer specified by customer_id does not exist') { 
  327. if (is_user_logged_in()) { 
  328. $customer_id = get_current_user_id(); 
  329. delete_user_meta($customer_id, 'braintree_customer_id'); 
  330. $clientToken = Braintree_ClientToken::generate(); 
  331. } else { 
  332. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  333. $this->add_log("Braintree_ClientToken::generate Braintree_Exception_NotFound" . $e->getMessage()); 
  334. wp_redirect($woocommerce->cart->get_cart_url()); 
  335. exit; 
  336. } catch (Exception $ex) { 
  337.  
  338. $this->add_log("Braintree_ClientToken::generate Exception:" . $ex->getMessage()); 
  339. wp_redirect($woocommerce->cart->get_cart_url()); 
  340. exit; 
  341. ?> 
  342. <div id="braintree-cc-form" class="wc-payment-form"> 
  343. <fieldset> 
  344. <div id="braintree-payment-form"></div> 
  345. </fieldset> 
  346. </div> 
  347. <script> 
  348. var $form = jQuery('form.checkout, #order_review'); 
  349. var ccForm = jQuery('form.checkout'); 
  350. var clientToken = "<?php echo $clientToken; ?>"; 
  351. braintree.setup(clientToken, "dropin", { 
  352. container: "braintree-payment-form",  
  353. onReady: function () { 
  354. jQuery.each(jQuery('#braintree-payment-form').children('iFrame'),  
  355. function (index) { 
  356. if (index > 0) { 
  357. jQuery(this).remove(); 
  358. }); 
  359. },  
  360. onError: function (a) { 
  361. if ("VALIDATION" === a.type) { 
  362. if (is_angelleye_braintree_selected()) { 
  363. console.log("configuration error " + a.message); 
  364. jQuery('.woocommerce-error, .braintree-token', ccForm).remove(); 
  365. ccForm.prepend('<ul class="woocommerce-error"><li>' + a.message + '</li></ul>'); 
  366. return $form.unblock(); 
  367. } else { 
  368. jQuery('.woocommerce-error, .braintree-token', ccForm).remove(); 
  369. ccForm.prepend('<ul class="woocommerce-error"><li>' + a.message + '</li></ul>'); 
  370. console.log("configuration error " + a.message); 
  371. return $form.unblock(); 
  372. },  
  373. onPaymentMethodReceived: function (obj) { 
  374. braintreeResponseHandler(obj); 
  375. }); 
  376.  
  377. function is_angelleye_braintree_selected() { 
  378. if (jQuery('#payment_method_braintree').is(':checked')) { 
  379. return true; 
  380. } else { 
  381. return false; 
  382. function braintreeResponseHandler(obj) { 
  383. var $form = jQuery('form.checkout, #order_review, #add_payment_method'),  
  384. ccForm = jQuery('#braintree-cc-form'); 
  385. if (obj.nonce) { 
  386. jQuery('.woocommerce-error, .braintree-token', ccForm).remove(); 
  387. ccForm.append('<input type="hidden" class="braintree-token" name="braintree_token" value="' + obj.nonce + '"/>'); 
  388. $form.submit(); 
  389. jQuery('form.checkout').on('checkout_place_order_braintree', function () { 
  390. return braintreeFormHandler(); 
  391. }); 
  392. function braintreeFormHandler() { 
  393. if (jQuery('#payment_method_braintree').is(':checked')) { 
  394. if (0 === jQuery('input.braintree-token').size()) { 
  395. return false; 
  396. return true; 
  397.  
  398. </script> 
  399. <?php 
  400. } else { 
  401. parent::payment_fields(); 
  402. do_action('payment_fields_saved_payment_methods', $this); 
  403.  
  404. private function get_posted_card() { 
  405. $card_number = isset($_POST['braintree-card-number']) ? wc_clean($_POST['braintree-card-number']) : ''; 
  406. $card_cvc = isset($_POST['braintree-card-cvc']) ? wc_clean($_POST['braintree-card-cvc']) : ''; 
  407. $card_expiry = isset($_POST['braintree-card-expiry']) ? wc_clean($_POST['braintree-card-expiry']) : ''; 
  408. $card_number = str_replace(array(' ', '-'), '', $card_number); 
  409. $card_expiry = array_map('trim', explode('/', $card_expiry)); 
  410. $card_exp_month = str_pad($card_expiry[0], 2, "0", STR_PAD_LEFT); 
  411. $card_exp_year = isset($card_expiry[1]) ? $card_expiry[1] : ''; 
  412. if (strlen($card_exp_year) == 2) { 
  413. $card_exp_year += 2000; 
  414. return (object) array( 
  415. 'number' => $card_number,  
  416. 'type' => '',  
  417. 'cvc' => $card_cvc,  
  418. 'exp_month' => $card_exp_month,  
  419. 'exp_year' => $card_exp_year,  
  420. ); 
  421.  
  422. /** 
  423. * Process the payment 
  424. */ 
  425. public function process_payment($order_id) { 
  426. $order = new WC_Order($order_id); 
  427. $success = $this->angelleye_do_payment($order); 
  428. if ($success == true) { 
  429. return array( 
  430. 'result' => 'success',  
  431. 'redirect' => $this->get_return_url($order) 
  432. ); 
  433. } else { 
  434. WC()->session->set( 'reload_checkout', true ); 
  435. return array( 
  436. 'result' => 'fail',  
  437. 'redirect' => '' 
  438. ); 
  439.  
  440. public function angelleye_do_payment($order) { 
  441. $success = true; 
  442. global $woocommerce; 
  443. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  444. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  445. try { 
  446. if ($this->enable_braintree_drop_in) { 
  447. $payment_method_nonce = self::get_posted_variable('braintree_token'); 
  448. if (empty($payment_method_nonce)) { 
  449. $this->add_log("Error: The payment_method_nonce was unexpectedly empty"); 
  450. wc_add_notice(__('Error: PayPal Powered by Braintree did not supply a payment nonce. Please try again later or use another means of payment.', 'paypal-for-woocommerce'), 'error'); 
  451. return false; 
  452.  
  453. $request_data = array(); 
  454. $this->angelleye_braintree_lib(); 
  455. $card = $this->get_posted_card(); 
  456.  
  457. $billing_company = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(); 
  458. $billing_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  459. $billing_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  460. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  461. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  462. $billing_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_city : $order->get_billing_city(); 
  463. $billing_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_postcode : $order->get_billing_postcode(); 
  464. $billing_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_country : $order->get_billing_country(); 
  465. $billing_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_state : $order->get_billing_state(); 
  466.  
  467. $request_data['billing'] = array( 
  468. 'firstName' => $billing_first_name,  
  469. 'lastName' => $billing_last_name,  
  470. 'company' => $billing_company,  
  471. 'streetAddress' => $billing_address_1,  
  472. 'extendedAddress' => $billing_address_2,  
  473. 'locality' => $billing_city,  
  474. 'region' => $billing_state,  
  475. 'postalCode' => $billing_postcode,  
  476. 'countryCodeAlpha2' => $billing_country,  
  477. ); 
  478.  
  479. $request_data['shipping'] = array( 
  480. 'firstName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(),  
  481. 'lastName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(),  
  482. 'company' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_company : $order->get_shipping_company(),  
  483. 'streetAddress' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(),  
  484. 'extendedAddress' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(),  
  485. 'locality' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(),  
  486. 'region' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(),  
  487. 'postalCode' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(),  
  488. 'countryCodeAlpha2' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(),  
  489. ); 
  490. if ($this->enable_braintree_drop_in == false) { 
  491. if ((!empty($_POST['wc-braintree-payment-token']) && $_POST['wc-braintree-payment-token'] == 'new') || empty($_POST['wc-braintree-payment-token'])) { 
  492. $billing_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  493. $billing_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  494. $request_data['creditCard'] = array( 
  495. 'number' => $card->number,  
  496. 'expirationDate' => $card->exp_month . '/' . $card->exp_year,  
  497. 'cvv' => $card->cvc,  
  498. 'cardholderName' => $billing_first_name . ' ' . $billing_last_name 
  499. ); 
  500. } else if (is_user_logged_in() && (!empty($_POST['wc-braintree-payment-token']) && $_POST['wc-braintree-payment-token'] != 'new')) { 
  501. $customer_id = get_current_user_id(); 
  502. $token_id = wc_clean($_POST['wc-braintree-payment-token']); 
  503. $token = WC_Payment_Tokens::get($token_id); 
  504. $braintree_customer_id = get_user_meta($customer_id, 'braintree_customer_id', true); 
  505. $request_data['paymentMethodToken'] = $token->get_token(); 
  506.  
  507. } else { 
  508. $request_data['paymentMethodNonce'] = $payment_method_nonce; 
  509. if (is_user_logged_in()) { 
  510. $customer_id = get_current_user_id(); 
  511. $braintree_customer_id = get_user_meta($customer_id, 'braintree_customer_id', true); 
  512. if (!empty($braintree_customer_id)) { 
  513. $request_data['customerId'] = $braintree_customer_id; 
  514. } else { 
  515. $request_data['customer'] = array( 
  516. 'firstName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(),  
  517. 'lastName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(),  
  518. 'company' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(),  
  519. 'phone' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_phone : $order->get_billing_phone(),  
  520. 'email' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_email : $order->get_billing_email(),  
  521. ); 
  522. $request_data['amount'] = number_format($order->get_total(), 2, '.', ''); 
  523. if (isset($this->merchant_account_id) && !empty($this->merchant_account_id)) { 
  524. $request_data['merchantAccountId'] = $this->merchant_account_id; 
  525. $request_data['orderId'] = $order->get_order_number(); 
  526. $request_data['options'] = $this->get_braintree_options(); 
  527. $request_data['channel'] = 'AngellEYEPayPalforWoo_BT'; 
  528. if (!empty($this->softdescriptor)) { 
  529. $request_data['descriptor'] = array('name' => $this->softdescriptor); 
  530.  
  531. if ($this->debug) { 
  532. $this->add_log('Begin Braintree_Transaction::sale request'); 
  533. $this->add_log('Order: ' . print_r($order->get_order_number(), true)); 
  534. $log = $request_data; 
  535. if ($this->enable_braintree_drop_in == false) { 
  536. $log['creditCard'] = array( 
  537. 'number' => '**** **** **** ****',  
  538. 'expirationDate' => '**' . '/' . '****',  
  539. 'cvv' => '***' 
  540. ); 
  541. } else { 
  542. $log['paymentMethodNonce'] = '*********************'; 
  543. $this->add_log('Braintree_Transaction::sale Reuest Data ' . print_r($log, true)); 
  544.  
  545. try { 
  546. $this->response = Braintree_Transaction::sale(apply_filters('angelleye_woocommerce_braintree_sale_request_args', $request_data)); 
  547. } catch (Braintree_Exception_Authentication $e) { 
  548. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  549. $this->add_log("Braintree_Transaction::sale Braintree_Exception_Authentication: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  550. $order->add_order_note("Braintree_Transaction::sale Braintree_Exception_Authentication: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  551. return $success = false; 
  552. } catch (Braintree_Exception_Authorization $e) { 
  553. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  554. $this->add_log("Braintree_Transaction::sale Braintree_Exception_Authorization: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  555. $order->add_order_note("Braintree_Transaction::sale Braintree_Exception_Authorization: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  556. return $success = false; 
  557. } catch (Braintree_Exception_DownForMaintenance $e) { 
  558. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  559. $this->add_log("Braintree_Transaction::sale Braintree_Exception_DownForMaintenance: Request times out."); 
  560. $order->add_order_note("Braintree_Transaction::sale Braintree_Exception_DownForMaintenance: Request times out."); 
  561. return $success = false; 
  562. } catch (Braintree_Exception_ServerError $e) { 
  563. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  564. $this->add_log("Braintree_Transaction::sale Braintree_Exception_ServerError " . $e->getMessage()); 
  565. $order->add_order_note("Braintree_Transaction::sale Braintree_Exception_ServerError " . $e->getMessage()); 
  566. return $success = false; 
  567. } catch (Braintree_Exception_SSLCertificate $e) { 
  568. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  569. $this->add_log("Braintree_Transaction::sale Braintree_Exception_SSLCertificate " . $e->getMessage()); 
  570. $order->add_order_note("Braintree_Transaction::sale Braintree_Exception_SSLCertificate " . $e->getMessage()); 
  571. return $success = false; 
  572. } catch (Exception $e) { 
  573. wc_add_notice(__('Error: PayPal Powered by Braintree was unable to complete the transaction. Please try again later or use another means of payment.', 'paypal-for-woocommerce'), 'error'); 
  574. $this->add_log('Error: Unable to complete transaction. Reason: ' . $e->getMessage()); 
  575. $order->add_order_note("Error: Unable to complete transaction. Reason: " . $e->getMessage()); 
  576. return $success = false; 
  577.  
  578. if (!$this->response->success) { 
  579. $notice = sprintf(__('Error: PayPal Powered by Braintree was unable to complete the transaction. Please try again later or use another means of payment. Reason: %s', 'paypal-for-woocommerce'), $this->response->message); 
  580. wc_add_notice($notice, 'error'); 
  581. $this->add_log("Error: Unable to complete transaction. Reason: {$this->response->message}"); 
  582. $order->add_order_note("Error: Unable to complete transaction. Reason: {$this->response->message}"); 
  583. return $success = false; 
  584.  
  585. $this->add_log('Braintree_Transaction::sale Response code: ' . print_r($this->get_status_code(), true)); 
  586. $this->add_log('Braintree_Transaction::sale Response message: ' . print_r($this->get_status_message(), true)); 
  587.  
  588. $maybe_settled_later = array( 
  589. 'settling',  
  590. 'settlement_pending',  
  591. 'submitted_for_settlement',  
  592. ); 
  593.  
  594. if (in_array($this->response->transaction->status, $maybe_settled_later)) { 
  595. if ($old_wc) { 
  596. update_post_meta($order_id, 'is_sandbox', $this->sandbox); 
  597. } else { 
  598. update_post_meta( $order->get_id(), 'is_sandbox', $this->sandbox ); 
  599. $order->payment_complete($this->response->transaction->id); 
  600. do_action('before_save_payment_token', $order_id); 
  601. if ((!empty($_POST['wc-braintree-payment-token']) && $_POST['wc-braintree-payment-token'] == 'new') || ( $this->enable_braintree_drop_in && $this->supports('tokenization'))) { 
  602. if ((!empty($_POST['wc-braintree-new-payment-method']) && $_POST['wc-braintree-new-payment-method'] == true) || ($this->enable_braintree_drop_in && $this->supports('tokenization'))) { 
  603. try { 
  604. $transaction = Braintree_Transaction::find($this->response->transaction->id); 
  605. if (!empty($transaction->creditCard) && !empty($transaction->customer['id'])) { 
  606. $customer_id = $order->get_user_id(); 
  607. update_user_meta($customer_id, 'braintree_customer_id', $transaction->customer['id']); 
  608. $payment_method_token = $transaction->creditCard['token']; 
  609. $wc_existing_token = $this->get_token_by_token($payment_method_token); 
  610. if ($wc_existing_token == null) { 
  611. $token = new WC_Payment_Token_CC(); 
  612. $token->set_user_id($customer_id); 
  613. $token->set_token($payment_method_token); 
  614. $token->set_gateway_id($this->id); 
  615. $token->set_card_type($transaction->creditCard['cardType']); 
  616. $token->set_last4($transaction->creditCard['last4']); 
  617. $token->set_expiry_month($transaction->creditCard['expirationMonth']); 
  618. $token->set_expiry_year($transaction->creditCard['expirationYear']); 
  619. $save_result = $token->save(); 
  620. $this->save_payment_token($order, $payment_method_token); 
  621. if ($save_result) { 
  622. $order->add_payment_token($token); 
  623. } else { 
  624. $order->add_payment_token($wc_existing_token); 
  625. } catch (Braintree_Exception_NotFound $e) { 
  626. $this->add_log("Braintree_Transaction::find Braintree_Exception_NotFound: " . $e->getMessage()); 
  627. return new WP_Error(404, $e->getMessage()); 
  628. } catch (Exception $ex) { 
  629. $this->add_log("Braintree_Transaction::find Exception: " . $ex->getMessage()); 
  630. return new WP_Error(404, $ex->getMessage()); 
  631. $order->payment_complete($this->response->transaction->id); 
  632. $order->add_order_note(sprintf(__('%s payment approved! Trnsaction ID: %s', 'paypal-for-woocommerce'), $this->title, $this->response->transaction->id)); 
  633. WC()->cart->empty_cart(); 
  634. } else { 
  635. $this->add_log(sprintf('Info: unhandled transaction id = %s, status = %s', $this->response->transaction->id, $this->response->transaction->status)); 
  636. $order->update_status('on-hold', sprintf(__('Transaction was submitted to PayPal Braintree but not handled by WooCommerce order, transaction_id: %s, status: %s. Order was put in-hold.', 'paypal-for-woocommerce'), $this->response->transaction->id, $this->response->transaction->status)); 
  637. } catch (Exception $ex) { 
  638. wc_add_notice($ex->getMessage(), 'error'); 
  639. return $success = false; 
  640. return $success; 
  641.  
  642. public function get_braintree_options() { 
  643. return array('submitForSettlement' => true, 'storeInVaultOnSuccess' => 'true'); 
  644.  
  645. public static function multibyte_loaded() { 
  646. return extension_loaded('mbstring'); 
  647.  
  648. public function process_refund($order_id, $amount = null, $reason = '') { 
  649. $order = wc_get_order($order_id); 
  650. if (!$order || !$order->get_transaction_id()) { 
  651. return false; 
  652.  
  653. $this->angelleye_braintree_lib(); 
  654.  
  655. try { 
  656. $transaction = Braintree_Transaction::find($order->get_transaction_id()); 
  657. } catch (Braintree_Exception_NotFound $e) { 
  658. $this->add_log("Braintree_Transaction::find Braintree_Exception_NotFound" . $e->getMessage()); 
  659. return new WP_Error(404, $e->getMessage()); 
  660. } catch (Braintree_Exception_Authentication $e) { 
  661. $this->add_log("Braintree_Transaction::find Braintree_Exception_Authentication: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  662. return new WP_Error(404, $e->getMessage()); 
  663. } catch (Braintree_Exception_Authorization $e) { 
  664. $this->add_log("Braintree_Transaction::find Braintree_Exception_Authorization: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  665. return new WP_Error(404, $e->getMessage()); 
  666. } catch (Braintree_Exception_DownForMaintenance $e) { 
  667. $this->add_log("Braintree_Transaction::find Braintree_Exception_DownForMaintenance: Request times out."); 
  668. return new WP_Error(404, $e->getMessage()); 
  669. } catch (Exception $e) { 
  670. $this->add_log($e->getMessage()); 
  671. return new WP_Error(404, $e->getMessage()); 
  672.  
  673. if (isset($transaction->status) && $transaction->status == 'submitted_for_settlement') { 
  674. if ($amount == $order->get_total()) { 
  675. try { 
  676. $result = Braintree_Transaction::void($order->get_transaction_id()); 
  677. if ($result->success) { 
  678. $order->add_order_note(sprintf(__('Refunded %s - Transaction ID: %s', 'paypal-for-woocommerce'), wc_price(number_format($amount, 2, '.', '')), $result->transaction->id)); 
  679. return true; 
  680. } else { 
  681. $error = ''; 
  682. foreach (($result->errors->deepAll()) as $error) { 
  683. return new WP_Error(404, 'ec_refund-error', $error->message); 
  684. } catch (Braintree_Exception_NotFound $e) { 
  685. $this->add_log("Braintree_Transaction::void Braintree_Exception_NotFound: " . $e->getMessage()); 
  686. return new WP_Error(404, $e->getMessage()); 
  687. } catch (Exception $ex) { 
  688. $this->add_log("Braintree_Transaction::void Exception: " . $e->getMessage()); 
  689. return new WP_Error(404, $e->getMessage()); 
  690. } else { 
  691. return new WP_Error(404, 'braintree_refund-error', __('Oops, you cannot partially void this order. Please use the full order amount.', 'paypal-for-woocommerce')); 
  692. } elseif (isset($transaction->status) && ($transaction->status == 'settled' || $transaction->status == 'settling')) { 
  693. try { 
  694. $result = Braintree_Transaction::refund($order->get_transaction_id(), $amount); 
  695. if ($result->success) { 
  696. $order->add_order_note(sprintf(__('Refunded %s - Transaction ID: %s', 'paypal-for-woocommerce'), wc_price(number_format($amount, 2, '.', '')), $result->transaction->id)); 
  697. return true; 
  698. } else { 
  699. $error = ''; 
  700. foreach (($result->errors->deepAll()) as $error) { 
  701. return new WP_Error(404, 'ec_refund-error', $error->message); 
  702. } catch (Braintree_Exception_NotFound $e) { 
  703. $this->add_log("Braintree_Transaction::refund Braintree_Exception_NotFound: " . $e->getMessage()); 
  704. return new WP_Error(404, $e->getMessage()); 
  705. } catch (Exception $ex) { 
  706. $this->add_log("Braintree_Transaction::refund Exception: " . $e->getMessage()); 
  707. return new WP_Error(404, $e->getMessage()); 
  708. } else { 
  709. $this->add_log("Error: The transaction cannot be voided nor refunded in its current state: state = {$transaction->status}"); 
  710. return new WP_Error(404, "Error: The transaction cannot be voided nor refunded in its current state: state = {$transaction->status}"); 
  711.  
  712. public function angelleye_braintree_lib() { 
  713. try { 
  714. require_once( 'lib/Braintree/Braintree.php' ); 
  715. Braintree_Configuration::environment($this->environment); 
  716. Braintree_Configuration::merchantId($this->merchant_id); 
  717. Braintree_Configuration::publicKey($this->public_key); 
  718. Braintree_Configuration::privateKey($this->private_key); 
  719. } catch (Exception $ex) { 
  720. $this->add_log('Error: Unable to Load Braintree. Reason: ' . $ex->getMessage()); 
  721. WP_Error(404, 'Error: Unable to Load Braintree. Reason: ' . $ex->getMessage()); 
  722.  
  723. public function add_dependencies_admin_notices() { 
  724. $missing_extensions = $this->get_missing_dependencies(); 
  725. if (count($missing_extensions) > 0) { 
  726. $message = sprintf( 
  727. _n( 
  728. '%s requires the %s PHP extension to function. Contact your host or server administrator to configure and install the missing extension.', '%s requires the following PHP extensions to function: %s. Contact your host or server administrator to configure and install the missing extensions.', count($missing_extensions), 'paypal-for-woocommerce' 
  729. ), "PayPal For WooCoomerce - Braintree", '<strong>' . implode(', ', $missing_extensions) . '</strong>' 
  730. ); 
  731. echo '<div class="error"><p>' . $message . '</p></div>'; 
  732.  
  733. public function get_missing_dependencies() { 
  734. $missing_extensions = array(); 
  735. foreach ($this->get_dependencies() as $ext) { 
  736. if (!extension_loaded($ext)) { 
  737. $missing_extensions[] = $ext; 
  738. return $missing_extensions; 
  739.  
  740. public function get_dependencies() { 
  741. return array('curl', 'dom', 'hash', 'openssl', 'SimpleXML', 'xmlwriter'); 
  742.  
  743. public function add_log($message) { 
  744. if ($this->debug == 'yes') { 
  745. if (empty($this->log)) 
  746. $this->log = new WC_Logger(); 
  747. $this->log->add('braintree', $message); 
  748.  
  749. public function get_status_code() { 
  750. if ($this->response->success) { 
  751. return $this->get_success_status_info('code'); 
  752. } else { 
  753. return $this->get_failure_status_info('code'); 
  754.  
  755. public function get_status_message() { 
  756. if ($this->response->success) { 
  757. return $this->get_success_status_info('message'); 
  758. } else { 
  759. return $this->get_failure_status_info('message'); 
  760.  
  761. public function get_success_status_info($type) { 
  762. $transaction = !empty($this->response->transaction) ? $this->response->transaction : $this->response->creditCardVerification; 
  763. if (isset($transaction->processorSettlementResponseCode) && !empty($transaction->processorSettlementResponseCode)) { 
  764. $status = array( 
  765. 'code' => $transaction->processorSettlementResponseCode,  
  766. 'message' => $transaction->processorSettlementResponseText,  
  767. ); 
  768. } else { 
  769. $status = array( 
  770. 'code' => $transaction->processorResponseCode,  
  771. 'message' => $transaction->processorResponseText,  
  772. ); 
  773. return isset($status[$type]) ? $status[$type] : null; 
  774.  
  775. public function get_failure_status_info($type) { 
  776. if ($this->has_validation_errors()) { 
  777. $errors = $this->get_validation_errors(); 
  778. return implode(', ', ( 'code' === $type ? array_keys($errors) : array_values($errors))); 
  779. $transaction = !empty($this->response->transaction) ? $this->response->transaction : $this->response->creditCardVerification; 
  780. switch ($transaction->status) { 
  781. case 'gateway_rejected': 
  782. $status = array( 
  783. 'code' => $transaction->gatewayRejectionReason,  
  784. 'message' => $this->response->message,  
  785. ); 
  786. break; 
  787. case 'processor_declined': 
  788. $status = array( 
  789. 'code' => $transaction->processorResponseCode,  
  790. 'message' => $transaction->processorResponseText . (!empty($transaction->additionalProcessorResponse) ? ' (' . $transaction->additionalProcessorResponse . ')' : '' ),  
  791. ); 
  792. break; 
  793. case 'settlement_declined': 
  794. $status = array( 
  795. 'code' => $transaction->processorSettlementResponseCode,  
  796. 'message' => $transaction->processorSettlementResponseText,  
  797. ); 
  798. break; 
  799. default: 
  800. $status = array( 
  801. 'code' => $transaction->status,  
  802. 'message' => $this->response->message,  
  803. ); 
  804. return isset($status[$type]) ? $status[$type] : null; 
  805.  
  806. public function has_validation_errors() { 
  807. return isset($this->response->errors) && $this->response->errors->deepSize(); 
  808.  
  809. public function get_validation_errors() { 
  810. $errors = array(); 
  811. if ($this->has_validation_errors()) { 
  812. foreach ($this->response->errors->deepAll() as $error) { 
  813. $errors[$error->code] = $error->message; 
  814. return $errors; 
  815.  
  816. public function get_user_message($message_id) { 
  817. $message = null; 
  818. switch ($message_id) { 
  819. case 'error': $message = __('An error occurred, please try again or try an alternate form of payment', 'paypal-for-woocommerce'); 
  820. break; 
  821. case 'decline': $message = __('We cannot process your order with the payment information that you provided. Please use a different payment account or an alternate payment method.', 'paypal-for-woocommerce'); 
  822. break; 
  823. case 'held_for_review': $message = __('This order is being placed on hold for review. Please contact us to complete the transaction.', 'paypal-for-woocommerce'); 
  824. break; 
  825. case 'held_for_incorrect_csc': $message = __('This order is being placed on hold for review due to an incorrect card verification number. You may contact the store to complete the transaction.', 'paypal-for-woocommerce'); 
  826. break; 
  827. case 'csc_invalid': $message = __('The card verification number is invalid, please try again.', 'paypal-for-woocommerce'); 
  828. break; 
  829. case 'csc_missing': $message = __('Please enter your card verification number and try again.', 'paypal-for-woocommerce'); 
  830. break; 
  831. case 'card_type_not_accepted': $message = __('That card type is not accepted, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  832. break; 
  833. case 'card_type_invalid': $message = __('The card type is invalid or does not correlate with the credit card number. Please try again or use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  834. break; 
  835. case 'card_type_missing': $message = __('Please select the card type and try again.', 'paypal-for-woocommerce'); 
  836. break; 
  837. case 'card_number_type_invalid': $message = __('The card type is invalid or does not correlate with the credit card number. Please try again or use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  838. break; 
  839. case 'card_number_invalid': $message = __('The card number is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  840. break; 
  841. case 'card_number_missing': $message = __('Please enter your card number and try again.', 'paypal-for-woocommerce'); 
  842. break; 
  843. case 'card_expiry_invalid': $message = __('The card expiration date is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  844. break; 
  845. case 'card_expiry_month_invalid': $message = __('The card expiration month is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  846. break; 
  847. case 'card_expiry_year_invalid': $message = __('The card expiration year is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  848. break; 
  849. case 'card_expiry_missing': $message = __('Please enter your card expiration date and try again.', 'paypal-for-woocommerce'); 
  850. break; 
  851. case 'bank_aba_invalid': $message_id = __('The bank routing number is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  852. break; 
  853. case 'bank_account_number_invalid': $message_id = __('The bank account number is invalid, please re-enter and try again.', 'paypal-for-woocommerce'); 
  854. break; 
  855. case 'card_expired': $message = __('The provided card is expired, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  856. break; 
  857. case 'card_declined': $message = __('The provided card was declined, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  858. break; 
  859. case 'insufficient_funds': $message = __('Insufficient funds in account, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  860. break; 
  861. case 'card_inactive': $message = __('The card is inactivate or not authorized for card-not-present transactions, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  862. break; 
  863. case 'credit_limit_reached': $message = __('The credit limit for the card has been reached, please use an alternate card or other form of payment.', 'paypal-for-woocommerce'); 
  864. break; 
  865. case 'csc_mismatch': $message = __('The card verification number does not match. Please re-enter and try again.', 'paypal-for-woocommerce'); 
  866. break; 
  867. case 'avs_mismatch': $message = __('The provided address does not match the billing address for cardholder. Please verify the address and try again.', 'paypal-for-woocommerce'); 
  868. break; 
  869. return apply_filters('wc_payment_gateway_transaction_response_user_message', $message, $message_id, $this); 
  870.  
  871. public function get_message() { 
  872. $messages = array(); 
  873. $message_id = array(); 
  874. $decline_codes = array( 
  875. 'cvv' => 'csc_mismatch',  
  876. 'avs' => 'avs_mismatch',  
  877. '2000' => 'card_declined',  
  878. '2001' => 'insufficient_funds',  
  879. '2002' => 'credit_limit_reached',  
  880. '2003' => 'card_declined',  
  881. '2004' => 'card_expired',  
  882. '2005' => 'card_number_invalid',  
  883. '2006' => 'card_expiry_invalid',  
  884. '2007' => 'card_type_invalid',  
  885. '2008' => 'card_number_invalid',  
  886. '2010' => 'csc_mismatch',  
  887. '2012' => 'card_declined',  
  888. '2013' => 'card_declined',  
  889. '2014' => 'card_declined',  
  890. '2016' => 'error',  
  891. '2017' => 'card_declined',  
  892. '2018' => 'card_declined',  
  893. '2023' => 'card_type_not_accepted',  
  894. '2024' => 'card_type_not_accepted',  
  895. '2038' => 'card_declined',  
  896. '2046' => 'card_declined',  
  897. '2056' => 'credit_limit_reached',  
  898. '2059' => 'avs_mismatch',  
  899. '2060' => 'avs_mismatch',  
  900. '2075' => 'paypal_closed',  
  901. ); 
  902. $response_codes = $this->get_validation_errors(); 
  903. if (isset($response_codes) && !empty($response_codes) && is_array($response_codes)) { 
  904. foreach ($response_codes as $key => $value) { 
  905. $messages[] = isset($decline_codes[$key]) ? $this->get_user_message($key) : $value; 
  906. return implode(' ', $messages); 
  907.  
  908. public function payment_scripts() { 
  909. if (!$this->is_available()) { 
  910. return; 
  911. if ($this->enable_braintree_drop_in) { 
  912. wp_enqueue_script('braintree-gateway', 'https://js.braintreegateway.com/js/braintree-2.29.0.min.js', array(), WC_VERSION, false); 
  913.  
  914. public static function get_posted_variable($variable, $default = '') { 
  915. return ( isset($_POST[$variable]) ? $_POST[$variable] : $default ); 
  916.  
  917. function get_transaction_url($order) { 
  918. $transaction_id = $order->get_transaction_id(); 
  919. if (empty($transaction_id)) { 
  920. return false; 
  921. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  922. $is_sandbox = $old_wc ? get_post_meta($order->id, 'is_sandbox', true) : get_post_meta($order->get_id(), 'is_sandbox', true); 
  923. if ($is_sandbox == true) { 
  924. $server = "sandbox.braintreegateway.com"; 
  925. } else { 
  926. if (empty($is_sandbox)) { 
  927. if ($this->sandbox == true) { 
  928. $server = "sandbox.braintreegateway.com"; 
  929. } else { 
  930. $server = "braintreegateway.com"; 
  931. } else { 
  932. $server = "braintreegateway.com"; 
  933. return "https://" . $server . "/merchants/" . urlencode($this->merchant_id) . "/transactions/" . urlencode($transaction_id); 
  934.  
  935. public function field_name($name) { 
  936. return ' name="' . esc_attr($this->id . '-' . $name) . '" '; 
  937.  
  938. public function angelleye_braintree_credit_card_form_fields($default_fields, $current_gateway_id) { 
  939. if ($current_gateway_id == $this->id) { 
  940. $fields = array( 
  941. 'card-number-field' => '<p class="form-row form-row-wide"> 
  942. <label for="' . esc_attr($this->id) . '-card-number">' . __('Card number', 'woocommerce') . ' <span class="required">*</span></label> 
  943. <input id="' . esc_attr($this->id) . '-card-number" class="input-text wc-credit-card-form-card-number" inputmode="numeric" autocomplete="cc-number" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" placeholder="•••• •••• •••• ••••" ' . $this->field_name('card-number') . ' /> 
  944. </p>',  
  945. 'card-expiry-field' => '<p class="form-row form-row-first"> 
  946. <label for="' . esc_attr($this->id) . '-card-expiry">' . __('Expiry (MM/YY)', 'woocommerce') . ' <span class="required">*</span></label> 
  947. <input id="' . esc_attr($this->id) . '-card-expiry" class="input-text wc-credit-card-form-card-expiry" inputmode="numeric" autocomplete="cc-exp" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" placeholder="' . esc_attr__('MM / YY', 'woocommerce') . '" ' . $this->field_name('card-expiry') . ' /> 
  948. </p>',  
  949. '<p class="form-row form-row-last"> 
  950. <label for="' . esc_attr($this->id) . '-card-cvc">' . __('Card code', 'woocommerce') . ' <span class="required">*</span></label> 
  951. <input id="' . esc_attr($this->id) . '-card-cvc" class="input-text wc-credit-card-form-card-cvc" inputmode="numeric" autocomplete="off" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" maxlength="4" placeholder="' . esc_attr__('CVC', 'woocommerce') . '" ' . $this->field_name('card-cvc') . ' style="width:100px" /> 
  952. </p>' 
  953. ); 
  954. return $fields; 
  955. } else { 
  956. return $default_fields; 
  957.  
  958. public function get_token_by_token($token_id, $token_result = null) { 
  959. global $wpdb; 
  960. if (is_null($token_result)) { 
  961. $token_result = $wpdb->get_row($wpdb->prepare( 
  962. "SELECT * FROM {$wpdb->prefix}woocommerce_payment_tokens WHERE token = %s", $token_id 
  963. )); 
  964. if (empty($token_result)) { 
  965. return null; 
  966. $token_class = 'WC_Payment_Token_' . $token_result->type; 
  967. if (class_exists($token_class)) { 
  968. $meta = get_metadata('payment_token', $token_result->token_id); 
  969. $passed_meta = array(); 
  970. if (!empty($meta)) { 
  971. foreach ($meta as $meta_key => $meta_value) { 
  972. $passed_meta[$meta_key] = $meta_value[0]; 
  973. return new $token_class($token_result->token_id, (array) $token_result, $passed_meta); 
  974. return null; 
  975.  
  976. public function add_payment_method($zero_amount_payment = false) { 
  977. $this->validate_fields(); 
  978. $this->angelleye_braintree_lib(); 
  979. $customer_id = get_current_user_id(); 
  980. $braintree_customer_id = get_user_meta($customer_id, 'braintree_customer_id', true); 
  981. if (!empty($braintree_customer_id)) { 
  982. $result = $this->braintree_create_payment_method($braintree_customer_id, $zero_amount_payment); 
  983. if ($result->success == true) { 
  984. $return = $this->braintree_save_payment_method($customer_id, $result, $zero_amount_payment); 
  985. return $return; 
  986. } else { 
  987. $braintree_customer_id = $this->braintree_create_customer($customer_id); 
  988. if (!empty($braintree_customer_id)) { 
  989. $result = $this->braintree_create_payment_method($braintree_customer_id, $zero_amount_payment); 
  990. if ($result->success == true) { 
  991. $return = $this->braintree_save_payment_method($customer_id, $result, $zero_amount_payment); 
  992. return $return; 
  993.  
  994. public function braintree_create_payment_method($braintree_customer_id, $zero_amount_payment = false) { 
  995. if ($this->enable_braintree_drop_in) { 
  996. $payment_method_nonce = self::get_posted_variable('braintree_token'); 
  997. if (!empty($payment_method_nonce)) { 
  998. $payment_method_request = array('customerId' => $braintree_customer_id, 'paymentMethodNonce' => $payment_method_nonce, 'options' => array('failOnDuplicatePaymentMethod' => true)); 
  999. if (isset($this->merchant_account_id) && !empty($this->merchant_account_id)) { 
  1000. $payment_method_request['options']['verificationMerchantAccountId'] = $this->merchant_account_id; 
  1001. } else { 
  1002. $this->add_log("Error: The payment_method_nonce was unexpectedly empty"); 
  1003. wc_add_notice(__('Error: PayPal Powered by Braintree did not supply a payment nonce. Please try again later or use another means of payment.', 'paypal-for-woocommerce'), 'error'); 
  1004. return false; 
  1005. } else { 
  1006. $card = $this->get_posted_card(); 
  1007. $payment_method_request = array('customerId' => $braintree_customer_id, 'cvv' => $card->cvc, 'expirationDate' => $card->exp_month . '/' . $card->exp_year, 'number' => $card->number); 
  1008. if (isset($this->merchant_account_id) && !empty($this->merchant_account_id)) { 
  1009. $payment_method_request['options']['verificationMerchantAccountId'] = $this->merchant_account_id; 
  1010. try { 
  1011. if ($this->enable_braintree_drop_in) { 
  1012. $result = Braintree_PaymentMethod::create($payment_method_request); 
  1013. } else { 
  1014. $result = Braintree_CreditCard::create($payment_method_request); 
  1015. return $result; 
  1016. } catch (Braintree_Exception_Authentication $e) { 
  1017. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  1018. $this->add_log("Braintree_ClientToken::generate Exception: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  1019. if ($zero_amount_payment == false) { 
  1020. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1021. exit; 
  1022. } else { 
  1023. return false; 
  1024. } catch (Braintree_Exception_Authorization $e) { 
  1025. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  1026. $this->add_log("Braintree_ClientToken::generate Exception: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  1027. if ($zero_amount_payment == false) { 
  1028. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1029. exit; 
  1030. } else { 
  1031. return false; 
  1032. } catch (Braintree_Exception_DownForMaintenance $e) { 
  1033. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  1034. $this->add_log("Braintree_ClientToken::generate Exception: Request times out."); 
  1035. if ($zero_amount_payment == false) { 
  1036. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1037. exit; 
  1038. } else { 
  1039. return false; 
  1040. } catch (Braintree_Exception_ServerError $e) { 
  1041. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  1042. $this->add_log("Braintree_ClientToken::generate Braintree_Exception_ServerError" . $e->getMessage()); 
  1043. if ($zero_amount_payment == false) { 
  1044. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1045. exit; 
  1046. } else { 
  1047. return false; 
  1048. } catch (Braintree_Exception_SSLCertificate $e) { 
  1049. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  1050. $this->add_log("Braintree_ClientToken::generate Braintree_Exception_SSLCertificate" . $e->getMessage()); 
  1051. if ($zero_amount_payment == false) { 
  1052. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1053. exit; 
  1054. } else { 
  1055. return false; 
  1056. } catch (Exception $ex) { 
  1057. $this->add_log("Braintree_ClientToken::generate Exception:" . $ex->getMessage()); 
  1058. if ($zero_amount_payment == false) { 
  1059. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1060. exit; 
  1061. } else { 
  1062. return false; 
  1063.  
  1064. public function braintree_save_payment_method($customer_id, $result) { 
  1065. if (!empty($result->paymentMethod)) { 
  1066. $braintree_method = $result->paymentMethod; 
  1067. } elseif ($result->creditCard) { 
  1068. $braintree_method = $result->creditCard; 
  1069. } else { 
  1070. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1071. exit; 
  1072. update_user_meta($customer_id, 'braintree_customer_id', $braintree_method->customerId); 
  1073. $payment_method_token = $braintree_method->token; 
  1074. $wc_existing_token = $this->get_token_by_token($payment_method_token); 
  1075. if ($wc_existing_token == null) { 
  1076. $token = new WC_Payment_Token_CC(); 
  1077. $token->set_user_id( $customer_id ); 
  1078. $token->set_token( $payment_method_token ); 
  1079. $token->set_gateway_id( $this->id ); 
  1080. $token->set_card_type( $braintree_method->cardType); 
  1081. $token->set_last4( $braintree_method->last4 ); 
  1082. $token->set_expiry_month( $braintree_method->expirationMonth ); 
  1083. $token->set_expiry_year( $braintree_method->expirationYear ); 
  1084. $save_result = $token->save(); 
  1085. if ($save_result) { 
  1086. return array( 
  1087. 'result' => 'success',  
  1088. '_payment_tokens_id' => $payment_method_token,  
  1089. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  1090. ); 
  1091. } else { 
  1092. if ($zero_amount_payment == false) { 
  1093. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1094. exit; 
  1095. } else { 
  1096. return array( 
  1097. 'result' => 'success',  
  1098. '_payment_tokens_id' => $payment_method_token,  
  1099. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  1100. ); 
  1101. } else { 
  1102. if ($zero_amount_payment == false) { 
  1103. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1104. exit; 
  1105. } else { 
  1106. return array( 
  1107. 'result' => 'success',  
  1108. '_payment_tokens_id' => $payment_method_token,  
  1109. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  1110. ); 
  1111. }  
  1112. }  
  1113.  
  1114. public function braintree_create_customer($customer_id) { 
  1115. $user = get_user_by('id', $customer_id); 
  1116. $firstName = (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); 
  1117. $lastName = (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); 
  1118. $company = (get_user_meta($customer_id, 'billing_company', true)) ? get_user_meta($customer_id, 'billing_company', true) : get_user_meta($customer_id, 'shipping_company', true); 
  1119. $billing_email = (get_user_meta($customer_id, 'billing_email', true)) ? get_user_meta($customer_id, 'billing_email', true) : get_user_meta($customer_id, 'shipping_last_name', true); 
  1120. $billing_email = ($billing_email) ? $billing_email : $user->user_email; 
  1121. $firstName = ($firstName) ? $firstName : $user->first_name; 
  1122. $lastName = ($lastName) ? $lastName : $user->last_name; 
  1123. $create_customer_request = array('firstName' => $firstName,  
  1124. 'lastName' => $lastName,  
  1125. 'company' => $company,  
  1126. 'email' => $billing_email,  
  1127. 'phone' => '',  
  1128. 'fax' => '',  
  1129. 'website' => '' 
  1130. ); 
  1131. $result = Braintree_Customer::create(apply_filters('angelleye_woocommerce_braintree_create_customer_request_args', $create_customer_request)); 
  1132. if ($result->success == true) { 
  1133. if (!empty($result->customer->id)) { 
  1134. update_user_meta($customer_id, 'braintree_customer_id', $result->customer->id); 
  1135. return $result->customer->id; 
  1136.  
  1137. public function subscription_process_payment($order_id) { 
  1138. $this->angelleye_braintree_lib(); 
  1139. $order = new WC_Order($order_id); 
  1140. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  1141. if (isset($_POST['wc-braintree-payment-token']) && 'new' !== $_POST['wc-braintree-payment-token']) { 
  1142. $token_id = wc_clean($_POST['wc-braintree-payment-token']); 
  1143. $token = WC_Payment_Tokens::get($token_id); 
  1144. if ($token->get_user_id() !== get_current_user_id()) { 
  1145. throw new Exception(__('Error processing checkout. Please try again.', 'paypal-for-woocommerce')); 
  1146. } else { 
  1147. $is_sandbox = $this->sandbox == 'no' ? false : true; 
  1148. update_post_meta($order_id, 'is_sandbox', $is_sandbox); 
  1149. $payment_tokens_id = $token->get_token(); 
  1150. $this->save_payment_token($order, $payment_tokens_id); 
  1151. $order->payment_complete($payment_tokens_id); 
  1152. WC()->cart->empty_cart(); 
  1153. $result = array( 
  1154. 'result' => 'success',  
  1155. 'redirect' => $this->get_return_url($order) 
  1156. ); 
  1157. if (is_ajax()) { 
  1158. wp_send_json($result); 
  1159. } else { 
  1160. wp_redirect($result['redirect']); 
  1161. exit; 
  1162. } else { 
  1163. $result = $this->add_payment_method($zero_amount_payment = true); 
  1164. if ($result['result'] == 'success') { 
  1165. $is_sandbox = $this->sandbox == 'no' ? false : true; 
  1166. update_post_meta($order_id, 'is_sandbox', $is_sandbox); 
  1167. $payment_tokens_id = (!empty($result['_payment_tokens_id'])) ? $result['_payment_tokens_id'] : ''; 
  1168. $this->save_payment_token($order, $payment_tokens_id); 
  1169. $order->payment_complete($payment_tokens_id); 
  1170. WC()->cart->empty_cart(); 
  1171. $result = array( 
  1172. 'result' => 'success',  
  1173. 'redirect' => $this->get_return_url($order) 
  1174. ); 
  1175. if (is_ajax()) { 
  1176. wp_send_json($result); 
  1177. } else { 
  1178. wp_redirect($result['redirect']); 
  1179. exit; 
  1180. } else { 
  1181. WC()->session->set( 'reload_checkout', true ); 
  1182. return array( 
  1183. 'result' => 'fail',  
  1184. 'redirect' => '' 
  1185. ); 
  1186.  
  1187. public function send_failed_order_email($order_id) { 
  1188. $emails = WC()->mailer()->get_emails(); 
  1189. if (!empty($emails) && !empty($order_id)) { 
  1190. $emails['WC_Email_Failed_Order']->trigger($order_id); 
  1191.  
  1192. public function save_payment_token($order, $payment_tokens_id) { 
  1193. // Store source in the order 
  1194. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  1195. if (!empty($payment_tokens_id)) { 
  1196. update_post_meta($order_id, '_payment_tokens_id', $payment_tokens_id); 
  1197.  
  1198. public function is_subscription($order_id) { 
  1199. return ( function_exists('wcs_order_contains_subscription') && ( wcs_order_contains_subscription($order_id) || wcs_is_subscription($order_id) || wcs_order_contains_renewal($order_id) ) ); 
  1200.  
  1201. public function process_subscription_payment($order, $amount) { 
  1202. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  1203. $request_data = array(); 
  1204. $this->angelleye_braintree_lib(); 
  1205.  
  1206. $billing_company = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(); 
  1207. $billing_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  1208. $billing_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  1209. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  1210. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  1211. $billing_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_city : $order->get_billing_city(); 
  1212. $billing_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_postcode : $order->get_billing_postcode(); 
  1213. $billing_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_country : $order->get_billing_country(); 
  1214. $billing_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_state : $order->get_billing_state(); 
  1215.  
  1216. $request_data['billing'] = array( 
  1217. 'firstName' => $billing_first_name,  
  1218. 'lastName' => $billing_last_name,  
  1219. 'company' => $billing_company,  
  1220. 'streetAddress' => $billing_address_1,  
  1221. 'extendedAddress' => $billing_address_2,  
  1222. 'locality' => $billing_city,  
  1223. 'region' => $billing_state,  
  1224. 'postalCode' => $billing_postcode,  
  1225. 'countryCodeAlpha2' => $billing_country,  
  1226. ); 
  1227.  
  1228. $request_data['shipping'] = array( 
  1229. 'firstName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(),  
  1230. 'lastName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(),  
  1231. 'company' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_company : $order->get_shipping_company(),  
  1232. 'streetAddress' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(),  
  1233. 'extendedAddress' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(),  
  1234. 'locality' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(),  
  1235. 'region' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(),  
  1236. 'postalCode' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(),  
  1237. 'countryCodeAlpha2' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(),  
  1238. ); 
  1239.  
  1240. if (!empty($order->subscription_renewal)) { 
  1241. $request_data['paymentMethodToken'] = get_post_meta($order_id, '_payment_tokens_id', true); 
  1242. if (is_user_logged_in()) { 
  1243. $customer_id = get_current_user_id(); 
  1244. $braintree_customer_id = get_user_meta($customer_id, 'braintree_customer_id', true); 
  1245. if (!empty($braintree_customer_id)) { 
  1246. $request_data['customerId'] = $braintree_customer_id; 
  1247. } else { 
  1248. $request_data['customer'] = array( 
  1249. 'firstName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(),  
  1250. 'lastName' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(),  
  1251. 'company' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_company : $order->get_billing_company(),  
  1252. 'phone' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_phone : $order->get_billing_phone(),  
  1253. 'email' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_email : $order->get_billing_email(),  
  1254. ); 
  1255. $request_data['amount'] = number_format($order->get_total(), 2, '.', ''); 
  1256. if (isset($this->merchant_account_id) && !empty($this->merchant_account_id)) { 
  1257. $request_data['merchantAccountId'] = $this->merchant_account_id; 
  1258. $request_data['orderId'] = $order->get_order_number(); 
  1259. $request_data['options'] = $this->get_braintree_options(); 
  1260. $request_data['channel'] = 'AngellEYEPayPalforWoo_BT'; 
  1261. if ($this->debug) { 
  1262. $this->add_log('Begin Braintree_Transaction::sale request'); 
  1263. $this->add_log('Order: ' . print_r($order->get_order_number(), true)); 
  1264. try { 
  1265. $this->response = Braintree_Transaction::sale($request_data); 
  1266. } catch (Braintree_Exception_Authentication $e) { 
  1267. $this->add_log("Braintree_Transaction::sale Braintree_Exception_Authentication: API keys are incorrect, Please double-check that you haven't accidentally tried to use your sandbox keys in production or vice-versa."); 
  1268. return $success = false; 
  1269. } catch (Braintree_Exception_Authorization $e) { 
  1270. $this->add_log("Braintree_Transaction::sale Braintree_Exception_Authorization: The API key that you're using is not authorized to perform the attempted action according to the role assigned to the user who owns the API key."); 
  1271. return $success = false; 
  1272. } catch (Braintree_Exception_DownForMaintenance $e) { 
  1273. $this->add_log("Braintree_Transaction::sale Braintree_Exception_DownForMaintenance: Request times out."); 
  1274. return $success = false; 
  1275. } catch (Braintree_Exception_ServerError $e) { 
  1276. $this->add_log("Braintree_Transaction::sale Braintree_Exception_ServerError " . $e->getMessage()); 
  1277. return $success = false; 
  1278. } catch (Braintree_Exception_SSLCertificate $e) { 
  1279. $this->add_log("Braintree_Transaction::sale Braintree_Exception_SSLCertificate " . $e->getMessage()); 
  1280. return $success = false; 
  1281. } catch (Exception $e) { 
  1282. $this->add_log('Error: Unable to complete transaction. Reason: ' . $e->getMessage()); 
  1283. return $success = false; 
  1284. if (!$this->response->success) { 
  1285. $this->add_log("Error: Unable to complete transaction. Reason: {$this->response->message}"); 
  1286. return $success = false; 
  1287. $this->add_log('Braintree_Transaction::sale Response code: ' . print_r($this->get_status_code(), true)); 
  1288. $this->add_log('Braintree_Transaction::sale Response message: ' . print_r($this->get_status_message(), true)); 
  1289. $maybe_settled_later = array( 
  1290. 'settling',  
  1291. 'settlement_pending',  
  1292. 'submitted_for_settlement',  
  1293. ); 
  1294. if (in_array($this->response->transaction->status, $maybe_settled_later)) { 
  1295. $is_sandbox = $this->sandbox == 'no' ? false : true; 
  1296. update_post_meta($order_id, 'is_sandbox', $is_sandbox); 
  1297. $order->payment_complete($this->response->transaction->id); 
  1298. $order->add_order_note(sprintf(__('%s payment approved! Trnsaction ID: %s', 'paypal-for-woocommerce'), $this->title, $this->response->transaction->id)); 
  1299. } else { 
  1300. $this->add_log(sprintf('Info: unhandled transaction id = %s, status = %s', $this->response->transaction->id, $this->response->transaction->status)); 
  1301. $order->update_status('on-hold', sprintf(__('Transaction was submitted to PayPal Braintree but not handled by WooCommerce order, transaction_id: %s, status: %s. Order was put in-hold.', 'paypal-for-woocommerce'), $this->response->transaction->id, $this->response->transaction->status)); 
  1302.  
  1303. public function angelleye_braintree_encrypt_gateway_api($settings) { 
  1304. if( !empty($settings['is_encrypt']) ) { 
  1305. $gateway_settings_key_array = array('sandbox_public_key', 'sandbox_private_key', 'sandbox_merchant_id', 'sandbox_merchant_account_id', 'public_key', 'private_key', 'merchant_id', 'merchant_account_id'); 
  1306. foreach ($gateway_settings_key_array as $gateway_settings_key => $gateway_settings_value) { 
  1307. if( !empty( $settings[$gateway_settings_value]) ) { 
  1308. $settings[$gateway_settings_value] = AngellEYE_Utility::crypting($settings[$gateway_settings_value], $action = 'e'); 
  1309. return $settings; 
  1310.