WC_Gateway_PayPal_Pro_PayFlow_AngellEYE

WC_Gateway_PayPal_Pro_PayFlow class.

Defined (1)

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

/classes/wc-gateway-paypal-pro-payflow-angelleye.php  
  1. class WC_Gateway_PayPal_Pro_PayFlow_AngellEYE extends WC_Payment_Gateway_CC { 
  2.  
  3. /** 
  4. * __construct function. 
  5. * @access public 
  6. * @return void 
  7. */ 
  8. public $customer_id; 
  9. function __construct() { 
  10. $this->id = 'paypal_pro_payflow'; 
  11. $this->method_title = __( 'PayPal Payments Pro 2.0 (PayFlow)', 'paypal-for-woocommerce' ); 
  12. $this->method_description = __( 'PayPal Payments Pro allows you to accept credit cards directly on your site without any redirection through PayPal. You host the checkout form on your own web server, so you will need an SSL certificate to ensure your customer data is protected.', 'paypal-for-woocommerce' ); 
  13. $this->has_fields = true; 
  14.  
  15. $this->allowed_currencies = apply_filters('woocommerce_paypal_pro_allowed_currencies', array('USD', 'EUR', 'GBP', 'CAD', 'JPY', 'AUD', 'NZD')); 
  16.  
  17.  
  18. // Load the form fields 
  19. $this->init_form_fields(); 
  20.  
  21. // Load the settings. 
  22. $this->init_settings(); 
  23.  
  24. // Get setting values 
  25. $this->title = $this->get_option('title'); 
  26. $this->description = $this->get_option('description'); 
  27. $this->enabled = $this->get_option('enabled'); 
  28. $this->testmode = 'yes' === $this->get_option('testmode', 'no'); 
  29. if( $this->testmode == false ) { 
  30. $this->testmode = AngellEYE_Utility::angelleye_paypal_for_woocommerce_is_set_sandbox_product(); 
  31. $this->invoice_id_prefix = $this->get_option('invoice_id_prefix', ''); 
  32. $this->debug = 'yes' === $this->get_option('debug', 'no'); 
  33. $this->error_email_notify = 'yes' === $this->get_option('error_email_notify', 'no'); 
  34. $this->error_display_type = $this->get_option('error_display_type', 'no'); 
  35. $this->send_items = 'yes' === $this->get_option('send_items', 'yes'); 
  36. $this->payment_action = $this->get_option('payment_action', 'Sale'); 
  37.  
  38. //fix ssl for image icon 
  39. $this->icon = $this->get_option('card_icon', plugins_url('/assets/images/payflow-cards.png', plugin_basename(dirname(__FILE__)))); 
  40. if (is_ssl()) { 
  41. $this->icon = preg_replace("/^http:/i", "https:", $this->icon); 
  42. $this->icon = apply_filters('woocommerce_paypal_pro_payflow_icon', $this->icon); 
  43. $this->paypal_partner = $this->get_option('paypal_partner', 'PayPal'); 
  44. $this->paypal_vendor = $this->get_option('paypal_vendor'); 
  45. $this->paypal_user = $this->get_option('paypal_user', $this->paypal_vendor); 
  46. $this->paypal_password = $this->get_option('paypal_password'); 
  47. if ($this->testmode == true) { 
  48. $this->paypal_vendor = $this->get_option('sandbox_paypal_vendor'); 
  49. $this->paypal_partner = $this->get_option('sandbox_paypal_partner', 'PayPal'); 
  50. $this->paypal_password = $this->get_option('sandbox_paypal_password'); 
  51. $this->paypal_user = $this->get_option('sandbox_paypal_user', $this->paypal_vendor); 
  52.  
  53. $this->supports = array( 
  54. 'products',  
  55. 'refunds' 
  56. ); 
  57.  
  58. $this->enable_tokenized_payments = $this->get_option('enable_tokenized_payments', 'no'); 
  59. if($this->enable_tokenized_payments == 'yes') { 
  60. $this->supports = array( 
  61. 'subscriptions',  
  62. 'products',  
  63. 'refunds',  
  64. 'subscription_cancellation',  
  65. 'subscription_reactivation',  
  66. 'subscription_suspension',  
  67. 'subscription_amount_changes',  
  68. 'subscription_payment_method_change', // Subs 1.n compatibility. 
  69. 'subscription_payment_method_change_customer',  
  70. 'subscription_payment_method_change_admin',  
  71. 'subscription_date_changes',  
  72. 'multiple_subscriptions',  
  73. 'add_payment_method',  
  74. 'tokenization' 
  75. ); 
  76.  
  77. $this->softdescriptor = $this->get_option('softdescriptor', ''); 
  78. $this->avs_cvv2_result_admin_email = 'yes' === $this->get_option('avs_cvv2_result_admin_email', 'no');  
  79. $this->Force_tls_one_point_two = get_option('Force_tls_one_point_two', 'no'); 
  80. $this->enable_cardholder_first_last_name = 'yes' === $this->get_option('enable_cardholder_first_last_name', 'no'); 
  81. $this->is_encrypt = $this->get_option('is_encrypt', 'no'); 
  82. $this->credit_card_month_field = $this->get_option('credit_card_month_field', 'names'); 
  83. $this->credit_card_year_field = $this->get_option('credit_card_year_field', 'four_digit'); 
  84. $this->fraud_management_filters = $this->get_option('fraud_management_filters', 'place_order_on_hold_for_further_review'); 
  85.  
  86. /** 2.0.0 */ 
  87. add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); 
  88.  
  89.  
  90. add_filter( 'woocommerce_credit_card_form_fields', array($this, 'angelleye_paypal_pro_payflow_credit_card_form_fields'), 10, 2); 
  91. add_filter('woocommerce_settings_api_sanitized_fields_' . $this->id, array($this, 'angelleye_paypal_pro_payflow_encrypt_gateway_api'), 10, 1); 
  92. if ($this->enable_cardholder_first_last_name) { 
  93. add_action('woocommerce_credit_card_form_start', array($this, 'angelleye_woocommerce_credit_card_form_start'), 10, 1); 
  94. if( $this->avs_cvv2_result_admin_email ) { 
  95. add_action( 'woocommerce_email_before_order_table', array( $this, 'angelleye_paypal_pro_payflow_email_instructions' ), 10, 3 ); 
  96.  
  97. $this->enable_automated_account_creation_for_guest_checkouts = 'yes' === $this->get_option('enable_automated_account_creation_for_guest_checkouts', 'no'); 
  98. $this->enable_guest_checkout = get_option('woocommerce_enable_guest_checkout') == 'yes' ? true : false; 
  99. if ($this->supports('tokenization') && is_checkout() && $this->enable_guest_checkout && !is_user_logged_in() && $this->enable_automated_account_creation_for_guest_checkouts) { 
  100. $this->enable_automated_account_creation_for_guest_checkouts = true; 
  101. add_action('woocommerce_after_checkout_validation', array($this, 'enable_automated_account_creation_for_guest_checkouts'), 10, 1); 
  102. } else { 
  103. $this->enable_automated_account_creation_for_guest_checkouts = false; 
  104.  
  105. $this->customer_id; 
  106. if (class_exists('WC_Gateway_Calculation_AngellEYE')) { 
  107. $this->calculation_angelleye = new WC_Gateway_Calculation_AngellEYE(); 
  108. } else { 
  109. require_once( PAYPAL_FOR_WOOCOMMERCE_PLUGIN_DIR . '/classes/wc-gateway-calculations-angelleye.php' ); 
  110. $this->calculation_angelleye = new WC_Gateway_Calculation_AngellEYE(); 
  111.  
  112.  
  113.  
  114. public function add_log($message) { 
  115. if ($this->debug) { 
  116. if (!isset($this->log)) { 
  117. $this->log = new WC_Logger(); 
  118. $this->log->add('paypal_payflow', $message); 
  119.  
  120. /** 
  121. * Initialise Gateway Settings Form Fields 
  122. */ 
  123. function init_form_fields() { 
  124.  
  125. $this->form_fields = array( 
  126. 'enabled' => array( 
  127. 'title' => __('Enable/Disable', 'paypal-for-woocommerce'),  
  128. 'label' => __('Enable PayPal Pro Payflow Edition', 'paypal-for-woocommerce'),  
  129. 'type' => 'checkbox',  
  130. 'description' => '',  
  131. 'default' => 'no' 
  132. ),  
  133. 'title' => array( 
  134. 'title' => __('Title', 'paypal-for-woocommerce'),  
  135. 'type' => 'text',  
  136. 'description' => __('This controls the title which the user sees during checkout.', 'paypal-for-woocommerce'),  
  137. 'default' => __('Credit card', 'paypal-for-woocommerce') 
  138. ),  
  139. 'description' => array( 
  140. 'title' => __('Description', 'paypal-for-woocommerce'),  
  141. 'type' => 'textarea',  
  142. 'description' => __('This controls the description which the user sees during checkout.', 'paypal-for-woocommerce'),  
  143. 'default' => __('Pay with your credit card.', 'paypal-for-woocommerce') 
  144. ),  
  145. 'testmode' => array( 
  146. 'title' => __('Test Mode', 'paypal-for-woocommerce'),  
  147. 'label' => __('Enable PayPal Sandbox/Test Mode', 'paypal-for-woocommerce'),  
  148. 'type' => 'checkbox',  
  149. 'description' => __('Place the payment gateway in development mode.', 'paypal-for-woocommerce'),  
  150. 'default' => 'no' 
  151. ),  
  152. 'invoice_id_prefix' => array( 
  153. 'title' => __('Invoice ID Prefix', 'paypal-for-woocommerce'),  
  154. 'type' => 'text',  
  155. 'description' => __('Add a prefix to the invoice ID sent to PayPal. This can resolve duplicate invoice problems when working with multiple websites on the same PayPal account.', 'paypal-for-woocommerce'),  
  156. ),  
  157. 'card_icon' => array( 
  158. 'title' => __('Card Icon', 'paypal-for-woocommerce'),  
  159. 'type' => 'text',  
  160. 'default' => plugins_url('/assets/images/payflow-cards.png', plugin_basename(dirname(__FILE__))),  
  161. 'class' => 'button_upload' 
  162. ),  
  163. 'debug' => array( 
  164. 'title' => __('Debug Log', 'paypal-for-woocommerce'),  
  165. 'type' => 'checkbox',  
  166. 'label' => __('Enable logging', 'paypal-for-woocommerce'),  
  167. 'default' => 'no',  
  168. 'description' => sprintf(__('Log PayPal events inside <code>%s</code>', 'paypal-for-woocommerce'), wc_get_log_file_path('paypal_payflow')),  
  169. ),  
  170. 'error_email_notify' => array( 
  171. 'title' => __('Error Email Notifications', 'paypal-for-woocommerce'),  
  172. 'type' => 'checkbox',  
  173. 'label' => __('Enable admin email notifications for errors.', 'paypal-for-woocommerce'),  
  174. 'default' => 'yes',  
  175. 'description' => __('This will send a detailed error email to the WordPress site administrator if a PayPal API error occurs.', 'paypal-for-woocommerce') 
  176. ),  
  177. 'error_display_type' => array( 
  178. 'title' => __('Error Display Type', 'paypal-for-woocommerce'),  
  179. 'type' => 'select',  
  180. 'label' => __('Display detailed or generic errors', 'paypal-for-woocommerce'),  
  181. 'class' => 'error_display_type_option',  
  182. 'options' => array( 
  183. 'detailed' => 'Detailed',  
  184. 'generic' => 'Generic' 
  185. ),  
  186. 'description' => __( 'Detailed displays actual errors returned from PayPal. Generic displays general errors that do not reveal details  
  187. and helps to prevent fraudulant activity on your site.' , 'paypal-for-woocommerce' ) 
  188. ),  
  189. 'sandbox_paypal_vendor' => array( 
  190. 'title' => __('Sandbox PayPal Vendor', 'paypal-for-woocommerce'),  
  191. 'type' => 'text',  
  192. 'description' => __('Your merchant login ID that you created when you registered for the account.', 'paypal-for-woocommerce'),  
  193. 'default' => '' 
  194. ),  
  195. 'sandbox_paypal_password' => array( 
  196. 'title' => __('Sandbox PayPal Password', 'paypal-for-woocommerce'),  
  197. 'type' => 'password',  
  198. 'description' => __('The password that you defined while registering for the account.', 'paypal-for-woocommerce'),  
  199. 'default' => '' 
  200. ),  
  201. 'sandbox_paypal_user' => array( 
  202. 'title' => __('Sandbox PayPal User', 'paypal-for-woocommerce'),  
  203. 'type' => 'text',  
  204. 'description' => __( 'If you set up one or more additional users on the account, this value is the ID 
  205. of the user authorized to process transactions. Otherwise, leave this field blank.', 'paypal-for-woocommerce' ),  
  206. 'default' => '' 
  207. ),  
  208.  
  209. 'sandbox_paypal_partner' => array( 
  210. 'title' => __( 'Sandbox PayPal Partner', 'paypal-for-woocommerce' ),  
  211. 'type' => 'text',  
  212. 'description' => __('The ID provided to you by the authorized PayPal Reseller who registered you for the Payflow SDK. If you purchased your account directly from PayPal, use PayPal or leave blank.', 'paypal-for-woocommerce'),  
  213. 'default' => 'PayPal' 
  214. ),  
  215. 'paypal_vendor' => array( 
  216. 'title' => __('Live PayPal Vendor', 'paypal-for-woocommerce'),  
  217. 'type' => 'text',  
  218. 'description' => __('Your merchant login ID that you created when you registered for the account.', 'paypal-for-woocommerce'),  
  219. 'default' => '' 
  220. ),  
  221. 'paypal_password' => array( 
  222. 'title' => __('Live PayPal Password', 'paypal-for-woocommerce'),  
  223. 'type' => 'password',  
  224. 'description' => __('The password that you defined while registering for the account.', 'paypal-for-woocommerce'),  
  225. 'default' => '' 
  226. ),  
  227. 'sandbox_paypal_user' => array( 
  228. 'title' => __('Sandbox PayPal User', 'paypal-for-woocommerce'),  
  229. 'type' => 'text',  
  230. 'description' => __('If you set up one or more additional users on the account, this value is the ID of the user authorized to process transactions. Otherwise, leave this field blank.', 'paypal-for-woocommerce'),  
  231. 'default' => '' 
  232. ),  
  233. 'sandbox_paypal_partner' => array( 
  234. 'title' => __('Sandbox PayPal Partner', 'paypal-for-woocommerce'),  
  235. 'type' => 'text',  
  236. 'description' => __('The ID provided to you by the authorized PayPal Reseller who registered you for the Payflow SDK. If you purchased your account directly from PayPal, use PayPal or leave blank.', 'paypal-for-woocommerce'),  
  237. ),  
  238. 'paypal_user' => array( 
  239. 'title' => __('Live PayPal User', 'paypal-for-woocommerce'),  
  240. 'type' => 'text',  
  241. 'description' => __( 'If you set up one or more additional users on the account, this value is the ID 
  242. of the user authorized to process transactions. Otherwise, leave this field blank.', 'paypal-for-woocommerce' ),  
  243. 'default' => '' 
  244. ),  
  245. 'paypal_partner' => array( 
  246. 'title' => __('Live PayPal Partner', 'paypal-for-woocommerce'),  
  247. 'type' => 'text',  
  248. 'description' => __( 'The ID provided to you by the authorized PayPal Reseller who registered you 
  249. for the Payflow SDK. If you purchased your account directly from PayPal, use PayPal or leave blank.', 'paypal-for-woocommerce' ),  
  250. 'default' => 'PayPal' 
  251. ),  
  252. 'send_items' => array( 
  253. 'title' => __('Send Item Details', 'paypal-for-woocommerce'),  
  254. 'label' => __('Send line item details to PayPal', 'paypal-for-woocommerce'),  
  255. 'type' => 'checkbox',  
  256. 'description' => __('Include all line item details in the payment request to PayPal so that they can be seen from the PayPal transaction details page.', 'paypal-for-woocommerce'),  
  257. 'default' => 'yes' 
  258. ),  
  259. 'payment_action' => array( 
  260. 'title' => __('Payment Action', 'paypal-for-woocommerce'),  
  261. 'label' => __('Whether to process as a Sale or Authorization.', 'paypal-for-woocommerce'),  
  262. 'description' => __('Sale will capture the funds immediately when the order is placed. Authorization will authorize the payment but will not capture the funds. You would need to capture funds through your PayPal account when you are ready to deliver.'),  
  263. 'type' => 'select',  
  264. 'options' => array( 
  265. 'Sale' => 'Sale',  
  266. 'Authorization' => 'Authorization',  
  267. ),  
  268. 'default' => 'Sale' 
  269. ),  
  270. 'softdescriptor' => array( 
  271. 'title' => __('Credit Card Statement Name', 'paypal-for-woocommerce'),  
  272. 'type' => 'text',  
  273. 'description' => __('The value entered here will be displayed on the buyer\'s credit card statement.', 'paypal-for-woocommerce'),  
  274. 'default' => '',  
  275. 'desc_tip' => true,  
  276. ),  
  277. 'fraud_management_filters' => array( 
  278. 'title' => __('Fraud Management Filters ', 'paypal-for-woocommerce'),  
  279. 'label' => '',  
  280. 'description' => __('Choose how you would like to handle orders when Fraud Management Filters are flagged.', 'paypal-for-woocommerce'),  
  281. 'type' => 'select',  
  282. 'class' => '',  
  283. 'options' => array( 
  284. 'ignore_warnings_and_proceed_as_usual' => __('Ignore warnings and proceed as usual.', 'paypal-for-woocommerce'),  
  285. 'place_order_on_hold_for_further_review' => __('Place order On Hold for further review.', 'paypal-for-woocommerce'),  
  286. ),  
  287. 'default' => 'place_order_on_hold_for_further_review',  
  288. 'desc_tip' => true,  
  289. ),  
  290. 'credit_card_month_field' => array( 
  291. 'title' => __('Credit Card Month Format', 'paypal-for-woocommerce'),  
  292. 'label' => __('Credit Card Month Display Format.', 'paypal-for-woocommerce'),  
  293. 'description' => __('Choose whether you wish to display Name format or Number format of Month field in the credit card form.'),  
  294. 'type' => 'select',  
  295. 'css' => 'max-width:200px;',  
  296. 'class' => 'wc-enhanced-select',  
  297. 'options' => array( 
  298. 'numbers' => 'Numbers',  
  299. 'names' => 'Names',  
  300. ),  
  301. 'default' => 'names' 
  302. ),  
  303. 'credit_card_year_field' => array( 
  304. 'title' => __('Credit Card Year Format', 'paypal-for-woocommerce'),  
  305. 'label' => __('Credit Card Year Display Format.', 'paypal-for-woocommerce'),  
  306. 'description' => __('Choose whether you wish to display two digit format or four digit of Year field in the credit card form.'),  
  307. 'type' => 'select',  
  308. 'css' => 'max-width:200px;',  
  309. 'class' => 'wc-enhanced-select',  
  310. 'options' => array( 
  311. 'two_digit' => 'Show Two Digit Years',  
  312. 'four_digit' => 'Show Four Digit Years',  
  313. ),  
  314. 'default' => 'four_digit' 
  315. ),  
  316. 'avs_cvv2_result_admin_email' => array( 
  317. 'title' => __('AVS / CVV2 Results in Admin Order Email', 'paypal-for-woocommerce'),  
  318. 'label' => __('Adds the AVS / CVV2 results to the admin order email notification', 'paypal-for-woocommerce'),  
  319. 'type' => 'checkbox',  
  320. 'description' => __('Display Address Verification Result (AVS) and Card Security Code Result (CVV2) Results in Admin Order Email.', 'paypal-for-woocommerce'),  
  321. 'default' => 'no',  
  322. 'desc_tip' => true,  
  323. ),  
  324. 'credit_card_month_field' => array( 
  325. 'title' => __('Choose Credit Card Month Field', 'paypal-for-woocommerce'),  
  326. 'label' => __('Choose Credit Card Month Field Format.', 'paypal-for-woocommerce'),  
  327. 'description' => __('Choose whether you wish to display Name format or Number format of Month field in the credit card form.'),  
  328. 'type' => 'select',  
  329. 'css' => 'max-width:200px;',  
  330. 'class' => 'wc-enhanced-select',  
  331. 'options' => array( 
  332. 'numbers' => 'Numbers',  
  333. 'names' => 'Names',  
  334. ),  
  335. 'default' => 'names' 
  336. ),  
  337. 'credit_card_year_field' => array( 
  338. 'title' => __('Choose Credit Card Year Field', 'paypal-for-woocommerce'),  
  339. 'label' => __('Choose Credit Card Year Field Format.', 'paypal-for-woocommerce'),  
  340. 'description' => __('Choose whether you wish to display Show Two digit format or Four digit of Year field in the credit card form.'),  
  341. 'type' => 'select',  
  342. 'css' => 'max-width:200px;',  
  343. 'class' => 'wc-enhanced-select',  
  344. 'options' => array( 
  345. 'two_digit' => 'Show Two Digit Years',  
  346. 'four_digit' => 'Show Four Digit Years',  
  347. ),  
  348. 'default' => 'four_digit' 
  349. ),  
  350. 'enable_tokenized_payments' => array( 
  351. 'title' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  352. 'label' => __('Enable Tokenized Payments', 'paypal-for-woocommerce'),  
  353. 'type' => 'checkbox',  
  354. 'description' => __('Allow buyers to securely save payment details to their account for quick checkout / auto-ship orders in the future.', 'paypal-for-woocommerce'),  
  355. 'default' => 'no',  
  356. 'class' => 'enable_tokenized_payments' 
  357. ),  
  358. 'enable_cardholder_first_last_name' => array( 
  359. 'title' => __('Enable Cardholder Name', 'paypal-for-woocommerce'),  
  360. 'label' => __('Adds fields for "card holder name" to checkout in addition to the "billing name" fields.', 'paypal-for-woocommerce'),  
  361. 'type' => 'checkbox',  
  362. 'description' => __('Display card holder first and last name in credit card form.', 'paypal-for-woocommerce'),  
  363. 'default' => 'no' 
  364. ),  
  365. 'is_encrypt' => array( 
  366. 'title' => __('', 'paypal-for-woocommerce'),  
  367. 'label' => __('', 'paypal-for-woocommerce'),  
  368. 'type' => 'hidden',  
  369. 'default' => 'yes',  
  370. 'class' => '' 
  371. ); 
  372. $this->form_fields = apply_filters('angelleye_fc_form_fields', $this->form_fields); 
  373.  
  374. /** 
  375. * Check if this gateway is enabled and available in the user's country 
  376. * This method no is used anywhere??? put above but need a fix below 
  377. */ 
  378. public function is_available() { 
  379.  
  380. if ( $this->enabled == "yes" ) { 
  381. if (!is_ssl() && !$this->testmode) { 
  382. return false; 
  383. // Currency check 
  384. if ( ! in_array( get_woocommerce_currency(), $this->allowed_currencies ) ) { 
  385. return false; 
  386.  
  387. // Required fields check 
  388. if ( ! $this->paypal_vendor || ! $this->paypal_password ) { 
  389. return false; 
  390.  
  391. return true; 
  392.  
  393. return false; 
  394.  
  395. /** 
  396. * Process the payment 
  397. */ 
  398. function process_payment($order_id) { 
  399. $order = new WC_Order($order_id); 
  400. $card_number = isset($_POST['paypal_pro_payflow-card-number']) ? wc_clean($_POST['paypal_pro_payflow-card-number']) : ''; 
  401. $card_cvc = isset($_POST['paypal_pro_payflow-card-cvc']) ? wc_clean($_POST['paypal_pro_payflow-card-cvc']) : ''; 
  402. $card_exp_year = isset($_POST['paypal_pro_payflow_card_expiration_year']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_year']) : ''; 
  403. $card_exp_month = isset($_POST['paypal_pro_payflow_card_expiration_month']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_month']) : ''; 
  404. $card_number = str_replace(array(' ', '-'), '', $card_number); 
  405. $card_type = AngellEYE_Utility::card_type_from_account_number($card_number); 
  406. if ($card_type == 'amex' && (get_woocommerce_currency() != 'USD' && get_woocommerce_currency() != 'AUD')) { 
  407. throw new Exception(__('Your processor is unable to process the Card Type in the currency requested. Please try another card type', 'paypal-for-woocommerce')); 
  408. if (strlen($card_exp_year) == 4) { 
  409. $card_exp_year = $card_exp_year - 2000; 
  410.  
  411. $card_exp_month = (int) $card_exp_month; 
  412. if ($card_exp_month < 10) { 
  413. $card_exp_month = '0' . $card_exp_month; 
  414. // Do payment with paypal 
  415. return $this->do_payment($order, $card_number, $card_exp_month . $card_exp_year, $card_cvc); 
  416.  
  417.  
  418.  
  419.  
  420. /** 
  421. * do_payment 
  422. * Process the PayFlow transaction with PayPal. 
  423. * @access public 
  424. * @param mixed $order 
  425. * @param mixed $card_number 
  426. * @param mixed $card_exp 
  427. * @param mixed $card_csc 
  428. * @param string $centinelPAResStatus (default: '') 
  429. * @param string $centinelEnrolled (default: '') 
  430. * @param string $centinelCavv (default: '') 
  431. * @param string $centinelEciFlag (default: '') 
  432. * @param string $centinelXid (default: '') 
  433. * @return void 
  434. */ 
  435. function do_payment($order, $card_number, $card_exp, $card_csc) { 
  436.  
  437. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  438.  
  439. if (!class_exists('Angelleye_PayPal')) { 
  440. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  441. if(!class_exists('Angelleye_PayPal_PayFlow' )) { 
  442. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php');  
  443.  
  444. /** 
  445. * Create PayPal_PayFlow object. 
  446. */ 
  447. $PayPalConfig = array( 
  448. 'Sandbox' => $this->testmode,  
  449. 'APIUsername' => $this->paypal_user,  
  450. 'APIPassword' => trim($this->paypal_password),  
  451. 'APIVendor' => $this->paypal_vendor,  
  452. 'APIPartner' => $this->paypal_partner,  
  453. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  454. ); 
  455. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  456.  
  457. try { 
  458.  
  459. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  460. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  461. $billtostreet = $billing_address_1 . ' ' . $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. $billing_email = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_email : $order->get_billing_email(); 
  467.  
  468. if(!empty($_POST['paypal_pro_payflow-card-cardholder-first'])) { 
  469. $firstname = wc_clean($_POST['paypal_pro_payflow-card-cardholder-first']); 
  470. } else { 
  471. $firstname = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  472. }  
  473.  
  474. if(!empty($_POST['paypal_pro_payflow-card-cardholder-last'])) { 
  475. $lastname = wc_clean($_POST['paypal_pro_payflow-card-cardholder-last']); 
  476. } else { 
  477. $lastname = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  478.  
  479. $PayPalRequestData = array( 
  480. 'tender'=>'C', // Required. The method of payment. Values are: A = ACH, C = Credit Card, D = Pinless Debit, K = Telecheck, P = PayPal 
  481. 'trxtype' => ($this->payment_action == 'Authorization' || $order->get_total() == 0 ) ? 'A' : 'S', // Required. Indicates the type of transaction to perform. Values are: A = Authorization, B = Balance Inquiry, C = Credit, D = Delayed Capture, F = Voice Authorization, I = Inquiry, L = Data Upload, N = Duplicate Transaction, S = Sale, V = Void 
  482. 'acct'=>$card_number, // Required for credit card transaction. Credit card or purchase card number. 
  483. 'expdate'=>$card_exp, // Required for credit card transaction. Expiration date of the credit card. Format: MMYY 
  484. 'amt'=> AngellEYE_Gateway_Paypal::number_format($order->get_total()), // Required. Amount of the transaction. Must have 2 decimal places.  
  485. 'currency'=>version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency(), //  
  486. 'dutyamt' => '', // 
  487. 'freightamt' => '', // 
  488. 'taxamt' => '', // 
  489. 'taxexempt' => '', // 
  490. 'custom' => apply_filters( 'ae_pppf_custom_parameter', json_encode( array( 'order_id' => version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(), 'order_key' => version_compare( WC_VERSION, '3.0', '<' ) ? $order->order_key : $order->get_order_key() ) ) , $order ), // Free-form field for your own use.  
  491. 'comment1'=> apply_filters( 'ae_pppf_comment1_parameter', '' , $order ), // Merchant-defined value for reporting and auditing purposes. 128 char max 
  492. 'comment2' => apply_filters('ae_pppf_comment2_parameter', '', $order), // Merchant-defined value for reporting and auditing purposes. 128 char max 
  493. 'cvv2' => $card_csc, // A code printed on the back of the card (or front for Amex) 
  494. 'recurring' => '', // Identifies the transaction as recurring. One of the following values: Y = transaction is recurring, N = transaction is not recurring. 
  495. 'swipe' => '', // Required for card-present transactions. Used to pass either Track 1 or Track 2, but not both. 
  496. 'orderid' => $this->invoice_id_prefix . preg_replace("/[^a-zA-Z0-9]/", "", $order->get_order_number()), // Checks for duplicate order. If you pass orderid in a request and pass it again in the future the response returns DUPLICATE=2 along with the orderid 
  497. 'orderdesc' => 'Order ' . $order->get_order_number() . ' on ' . get_bloginfo('name'), // 
  498. 'billtoemail'=>$billing_email, // Account holder's email address. 
  499. 'billtophonenum' => '', // Account holder's phone number. 
  500. 'billtofirstname' => $firstname, // Account holder's first name. 
  501. 'billtomiddlename' => '', // Account holder's middle name. 
  502. 'billtolastname' => $lastname, // Account holder's last name. 
  503. 'billtostreet'=> $billtostreet, // The cardholder's street address (number and street name). 150 char max 
  504. 'billtocity'=>$billing_city, // Bill to city. 45 char max 
  505. 'billtostate'=>$billing_state, // Bill to state.  
  506. 'billtozip'=>$billing_postcode, // Account holder's 5 to 9 digit postal code. 9 char max. No dashes, spaces, or non-numeric characters 
  507. 'billtocountry'=>$billing_country, // Bill to Country. 3 letter country code. 
  508. 'origid' => '', // Required by some transaction types. ID of the original transaction referenced. The PNREF parameter returns this ID, and it appears as the Transaction ID in PayPal Manager reports. 
  509. 'custref' => '', // 
  510. 'custcode' => '', // 
  511. 'custip' => $this->get_user_ip(), // 
  512. 'invnum'=> $this->invoice_id_prefix . preg_replace("/[^a-zA-Z0-9]/", "", str_replace("#", "", $order->get_order_number())), // 
  513. 'ponum' => '', // 
  514. 'starttime' => '', // For inquiry transaction when using CUSTREF to specify the transaction. 
  515. 'endtime' => '', // For inquiry transaction when using CUSTREF to specify the transaction. 
  516. 'securetoken' => '', // Required if using secure tokens. A value the Payflow server created upon your request for storing transaction data. 32 char 
  517. 'partialauth' => '', // Required for partial authorizations. Set to Y to submit a partial auth. 
  518. 'authcode'=>'', // Rrequired for voice authorizations. Returned only for approved voice authorization transactions. AUTHCODE is the approval code received over the phone from the processing network. 6 char max 
  519. 'merchdescr' => $this->softdescriptor 
  520. ); 
  521.  
  522. /** 
  523. * Shipping info 
  524. */ 
  525. $shipping_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(); 
  526. if($shipping_address_1) 
  527.  
  528.  
  529. $shipping_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(); 
  530. $PayPalRequestData['SHIPTOFIRSTNAME'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(); 
  531. $PayPalRequestData['SHIPTOLASTNAME'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(); 
  532. $PayPalRequestData['SHIPTOSTREET'] = $shipping_address_1 . ' ' . $shipping_address_2; 
  533. $PayPalRequestData['SHIPTOCITY'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(); 
  534. $PayPalRequestData['SHIPTOSTATE'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(); 
  535. $PayPalRequestData['SHIPTOCOUNTRY'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(); 
  536. $PayPalRequestData['SHIPTOZIP'] = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(); 
  537.  
  538. $PaymentData = AngellEYE_Gateway_Paypal::calculate($order, $this->send_items); 
  539. $OrderItems = array(); 
  540. if ($this->send_items) { 
  541. $item_loop = 0; 
  542. foreach ($PaymentData['order_items'] as $_item) { 
  543. $Item['L_NUMBER' . $item_loop] = $_item['number']; 
  544. $Item['L_NAME' . $item_loop] = $_item['name']; 
  545. $Item['L_COST' . $item_loop] = $_item['amt']; 
  546. $Item['L_QTY' . $item_loop] = $_item['qty']; 
  547. if ($_item['number']) { 
  548. $Item['L_SKU' . $item_loop] = $_item['number']; 
  549. $OrderItems = array_merge($OrderItems, $Item); 
  550. $item_loop++; 
  551.  
  552. /** 
  553. * Shipping/tax/item amount 
  554. */ 
  555. $PayPalRequestData['taxamt'] = $PaymentData['taxamt']; 
  556. $PayPalRequestData['freightamt'] = $PaymentData['shippingamt']; 
  557. $PayPalRequestData['ITEMAMT'] = $PaymentData['itemamt']; 
  558.  
  559. if ($this->send_items) { 
  560. $PayPalRequestData = array_merge($PayPalRequestData, $OrderItems); 
  561.  
  562.  
  563. $log = $PayPalRequestData; 
  564. if(!empty($_POST['wc-paypal_pro_payflow-payment-token']) && $_POST['wc-paypal_pro_payflow-payment-token'] != 'new') { 
  565. $token_id = wc_clean( $_POST['wc-paypal_pro_payflow-payment-token'] ); 
  566. $token = WC_Payment_Tokens::get( $token_id ); 
  567. $PayPalRequestData['origid'] = $token->get_token(); 
  568. $PayPalRequestData['expdate'] = ''; 
  569. } else { 
  570. $log['acct'] = '****'; 
  571. $log['cvv2'] = '****'; 
  572. if (!empty($order->subscription_renewal)) { 
  573. $PayPalRequestData['origid'] = get_post_meta($order_id, '_payment_tokens', true); 
  574. $this->add_log('PayFlow Request: '.print_r( $log, true ) ); 
  575. $PayPalResult = $PayPal->ProcessTransaction(apply_filters('angelleye_woocommerce_paypal_pro_payflow_process_transaction_request_args', $PayPalRequestData)); 
  576.  
  577. /** 
  578. * cURL Error Handling #146 
  579. * @since 1.1.8 
  580. */ 
  581.  
  582. AngellEYE_Gateway_Paypal::angelleye_paypal_for_woocommerce_curl_error_handler($PayPalResult, $methos_name = 'do_payment', $gateway = 'PayPal Payments Pro 2.0 (PayFlow)', $this->error_email_notify); 
  583.  
  584.  
  585. $this->add_log('PayFlow Endpoint: ' . $PayPal->APIEndPoint); 
  586. $this->add_log('PayFlow Response: ' . print_r($PayPalResult, true)); 
  587.  
  588.  
  589. /** 
  590. * Error check 
  591. */ 
  592. if (empty($PayPalResult['RAWRESPONSE'])) { 
  593. $fc_empty_response = apply_filters( 'ae_pppf_paypal_response_empty_message', __('Empty PayPal response.', 'paypal-for-woocommerce'), $PayPalResult ); 
  594. throw new Exception( $fc_empty_response ); 
  595.  
  596. /** 
  597. * Check for errors or fraud filter warnings and proceed accordingly. 
  598. */ 
  599. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 0 || $PayPalResult['RESULT'] == 126)) { 
  600. // Add order note 
  601. if ($PayPalResult['RESULT'] == 126) { 
  602. $order->add_order_note( $PayPalResult['RESPMSG']); 
  603. $order->add_order_note( $PayPalResult['PREFPSMSG']); 
  604. $order->add_order_note( "The payment was flagged by a fraud filter, please check your PayPal Manager account to review and accept or deny the payment."); 
  605. else 
  606.  
  607. if (isset($PayPalResult['PPREF']) && !empty($PayPalResult['PPREF'])) { 
  608.  
  609. add_post_meta($order_id, 'PPREF', $PayPalResult['PPREF']); 
  610. $order->add_order_note(sprintf(__('PayPal Pro payment completed (PNREF: %s) (PPREF: %s)', 'paypal-for-woocommerce'), $PayPalResult['PNREF'], $PayPalResult['PPREF'])); 
  611. } else { 
  612. $order->add_order_note(sprintf(__('PayPal Pro payment completed (PNREF: %s)', 'paypal-for-woocommerce'), $PayPalResult['PNREF'])); 
  613. /** Checkout Note */ 
  614. if (isset($_POST) && !empty($_POST['order_comments'])) { 
  615. // Update post 37 
  616. $checkout_note = array( 
  617. 'ID' => $order_id,  
  618. 'post_excerpt' => $_POST['order_comments'],  
  619. ); 
  620. wp_update_post($checkout_note); 
  621.  
  622. /** 
  623. * Add order notes for AVS result 
  624. */ 
  625. $avs_address_response_code = isset($PayPalResult['AVSADDR']) ? $PayPalResult['AVSADDR'] : ''; 
  626. $avs_zip_response_code = isset($PayPalResult['AVSZIP']) ? $PayPalResult['AVSZIP'] : ''; 
  627.  
  628. $avs_response_order_note = __('Address Verification Result', 'paypal-for-woocommerce'); 
  629. $avs_response_order_note .= "\n"; 
  630. $avs_response_order_note .= sprintf(__('Address Match: %s', 'paypal-for-woocommerce'), $avs_address_response_code); 
  631. $avs_response_order_note .= "\n"; 
  632. $avs_response_order_note .= sprintf(__('Postal Match: %s', 'paypal-for-woocommerce'), $avs_zip_response_code); 
  633.  
  634. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  635. if ($old_wc) { 
  636. update_post_meta($order_id, '_AVSADDR', $avs_address_response_code); 
  637. update_post_meta($order_id, '_AVSZIP', $avs_zip_response_code); 
  638. } else { 
  639. update_post_meta($order->get_id(), '_AVSADDR', $avs_address_response_code); 
  640. update_post_meta($order->get_id(), '_AVSZIP', $avs_zip_response_code); 
  641. $order->add_order_note($avs_response_order_note); 
  642.  
  643. /** 
  644. * Add order notes for CVV2 result 
  645. */ 
  646. $cvv2_response_code = isset($PayPalResult['CVV2MATCH']) ? $PayPalResult['CVV2MATCH'] : ''; 
  647. $cvv2_response_order_note = __('Card Security Code Result', 'paypal-for-woocommerce'); 
  648. $cvv2_response_order_note .= "\n"; 
  649. $cvv2_response_order_note .= sprintf(__('CVV2 Match: %s', 'paypal-for-woocommerce'), $cvv2_response_code); 
  650.  
  651. if ($old_wc) { 
  652. update_post_meta($order_id, '_CVV2MATCH', $cvv2_response_code); 
  653. } else { 
  654. update_post_meta($order->get_id(), '_CVV2MATCH', $cvv2_response_code); 
  655.  
  656. $order->add_order_note($cvv2_response_order_note); 
  657.  
  658. // Payment complete 
  659. //$order->add_order_note("PayPal Result".print_r($PayPalResult, true)); 
  660. do_action('before_save_payment_token', $order_id);  
  661. if(!empty($_POST['wc-paypal_pro_payflow-payment-token']) && $_POST['wc-paypal_pro_payflow-payment-token'] == 'new') { 
  662. if(!empty($_POST['wc-paypal_pro_payflow-new-payment-method']) && $_POST['wc-paypal_pro_payflow-new-payment-method'] == true) { 
  663. $customer_id = $order->get_user_id(); 
  664. $TRANSACTIONID = $PayPalResult['PNREF']; 
  665. $this->are_reference_transactions_enabled($TRANSACTIONID); 
  666. $token = new WC_Payment_Token_CC(); 
  667. $token->set_user_id($customer_id); 
  668. $token->set_token($TRANSACTIONID); 
  669. $token->set_gateway_id($this->id); 
  670. $token->set_card_type(AngellEYE_Utility::card_type_from_account_number($PayPalRequestData['acct'])); 
  671. $token->set_last4(substr($PayPalRequestData['acct'], -4)); 
  672. $token->set_expiry_month( substr( $PayPalRequestData['expdate'], 0, 2 ) ); 
  673. $expiry_year = substr( $PayPalRequestData['expdate'], 2, 3 ); 
  674. if ( strlen( $expiry_year ) == 2 ) { 
  675. $expiry_year = $expiry_year + 2000; 
  676. $token->set_expiry_year( $expiry_year ); 
  677. $save_result = $token->save(); 
  678. if ($save_result) { 
  679. $order->add_payment_token($token); 
  680. if($this->fraud_management_filters == 'place_order_on_hold_for_further_review' && $PayPalResult['RESULT'] == 126) { 
  681. $order->update_status('on-hold', $PayPalResult['RESPMSG']); 
  682. } else { 
  683. $order->payment_complete($PayPalResult['PNREF']); 
  684.  
  685.  
  686. // Remove cart 
  687. WC()->cart->empty_cart(); 
  688.  
  689. // Return thank you page redirect 
  690. return array( 
  691. 'result' => 'success',  
  692. 'redirect' => $this->get_return_url($order) 
  693. ); 
  694. else 
  695. $order->update_status('failed', __('PayPal Pro payment failed. Payment was rejected due to an error: ', 'paypal-for-woocommerce') . '(' . $PayPalResult['RESULT'] . ') ' . '"' . $PayPalResult['RESPMSG'] . '"'); 
  696.  
  697. // Generate error message based on Error Display Type setting 
  698. if($this->error_display_type == 'detailed') 
  699. $fc_error_display_type = __('Payment error:', 'paypal-for-woocommerce') . ' ' . $PayPalResult['RESULT'] . '-' . $PayPalResult['RESPMSG']; 
  700. else 
  701. $fc_error_display_type = __('Payment error:', 'paypal-for-woocommerce') . ' There was a problem processing your payment. Please try another method.'; 
  702. $fc_error_display_type = apply_filters('ae_pppf_error_user_display_message', $fc_error_display_type, $PayPalResult['RESULT'], $PayPalResult['RESPMSG'], $PayPalResult); 
  703. wc_add_notice($fc_error_display_type, "error"); 
  704.  
  705. // Notice admin if has any issue from PayPal 
  706. if($this->error_email_notify) 
  707. $admin_email = get_option("admin_email"); 
  708. $message = __("PayFlow API call failed.", "paypal-for-woocommerce") . "\n\n"; 
  709. $message .= __('Error Code: ', 'paypal-for-woocommerce') . $PayPalResult['RESULT'] . "\n"; 
  710. $message .= __('Detailed Error Message: ', 'paypal-for-woocommerce') . $PayPalResult['RESPMSG']; 
  711. $message .= isset($PayPalResult['PREFPSMSG']) && $PayPalResult['PREFPSMSG'] != '' ? ' - ' . $PayPalResult['PREFPSMSG'] . "\n" : "\n"; 
  712. $message .= __('User IP: ', 'paypal-for-woocommerce') . $this->get_user_ip() . "\n"; 
  713. $message .= __( 'Order ID: ' ).$order_id ."\n"; 
  714. $message .= __( 'Customer Name: ' ).$firstname.' '.$lastname."\n"; 
  715. $message .= __( 'Customer Email: ' ).$billing_email."\n"; 
  716. $message = apply_filters('ae_pppf_error_email_message', $message); 
  717. $subject = apply_filters('ae_pppf_error_email_subject', "PayPal Pro Error Notification"); 
  718. wp_mail($admin_email, $subject, $message); 
  719.  
  720. return; 
  721.  
  722. } catch (Exception $e) { 
  723. if ($order->has_status(array('pending', 'failed'))) { 
  724. $this->send_failed_order_email($order_id); 
  725. $fc_connect_error = apply_filters('angelleye_fc_connect_error', $e->getMessage(), $e); 
  726. wc_add_notice($fc_connect_error, "error"); 
  727. return;  
  728.  
  729.  
  730. public function payment_fields() { 
  731. do_action('angelleye_before_fc_payment_fields', $this); 
  732. if ($this->description) { 
  733. echo '<p>' . wp_kses_post($this->description); 
  734. if($this->testmode == true) 
  735. echo '<p>'; 
  736. _e('NOTICE: SANDBOX (TEST) MODE ENABLED.', 'paypal-for-woocommerce'); 
  737. echo '<br />'; 
  738. _e('For testing purposes you can use the card number 4111111111111111 with any CVC and a valid expiration date.', 'paypal-for-woocommerce'); 
  739. echo '</p>'; 
  740. parent::payment_fields(); 
  741. do_action('payment_fields_saved_payment_methods', $this); 
  742.  
  743. public function paypal_for_woocommerce_paypal_pro_payflow_credit_card_form_expiration_date_selectbox() { 
  744. $form_html = ""; 
  745. $form_html .= '<p class="form-row form-row-first">'; 
  746. $form_html .= '<label for="cc-expire-month">' . __("Expiration Date", 'paypal-for-woocommerce') . '<span class="required">*</span></label>'; 
  747. $form_html .= '<select name="paypal_pro_payflow_card_expiration_month" id="cc-expire-month" class="woocommerce-select woocommerce-cc-month mr5">'; 
  748. $form_html .= '<option value="">' . __('Month', 'paypal-for-woocommerce') . '</option>'; 
  749. $months = array(); 
  750. for ($i = 1; $i <= 12; $i++) : 
  751. $timestamp = mktime(0, 0, 0, $i, 1); 
  752. $months[date('n', $timestamp)] = date_i18n(_x('F', 'Month Names', 'paypal-for-woocommerce'), $timestamp); 
  753. endfor; 
  754. foreach ($months as $num => $name) { 
  755. if($this->credit_card_month_field == 'names') { 
  756. $form_html .= '<option value=' . $num . '>' . $name . '</option>'; 
  757. } else { 
  758. $month_value = ($num < 10) ? '0'.$num : $num; 
  759. $form_html .= '<option value=' . $num . '>' . $month_value . '</option>'; 
  760. $form_html .= '</select>'; 
  761. $form_html .= '<select name="paypal_pro_payflow_card_expiration_year" id="cc-expire-year" class="woocommerce-select woocommerce-cc-year ml5">'; 
  762. $form_html .= '<option value="">' . __('Year', 'paypal-for-woocommerce') . '</option>'; 
  763. for ($i = date('y'); $i <= date('y') + 15; $i++) { 
  764. if($this->credit_card_year_field == 'four_digit') { 
  765. $form_html .= '<option value=' . $i . '>20' . $i . '</option>'; 
  766. } else { 
  767. $form_html .= '<option value=' . $i . '>' . $i . '</option>'; 
  768. $form_html .= '</select>'; 
  769. $form_html .= '</p>'; 
  770. return $form_html; 
  771.  
  772.  
  773. /** 
  774. * Get user's IP address 
  775. */ 
  776. function get_user_ip() { 
  777. return !empty($_SERVER['HTTP_X_FORWARD_FOR']) ? $_SERVER['HTTP_X_FORWARD_FOR'] : $_SERVER['REMOTE_ADDR']; 
  778.  
  779. /** 
  780. * clear_centinel_session function. 
  781. * @access public 
  782. * @return void 
  783. */ 
  784. function clear_centinel_session() { 
  785. unset($_SESSION['Message']); 
  786. foreach ($_SESSION as $key => $value) { 
  787. if (preg_match("/^Centinel_.*/", $key) > 0) { 
  788. unset($_SESSION[$key]); 
  789.  
  790. /** 
  791. * Process a refund if supported 
  792. * @param int $order_id 
  793. * @param float $amount 
  794. * @param string $reason 
  795. * @return bool|wp_error True or false based on success, or a WP_Error object 
  796. */ 
  797. public function process_refund($order_id, $amount = null, $reason = '') { 
  798.  
  799. do_action('angelleye_before_fc_refund', $order_id, $amount, $reason); 
  800.  
  801. $order = wc_get_order($order_id); 
  802. $this->add_log('Begin Refund'); 
  803. $this->add_log('Order ID: ' . print_r($order_id, true)); 
  804. $this->add_log('Transaction ID: ' . print_r($order->get_transaction_id(), true)); 
  805. if (!$order || !$order->get_transaction_id() || !$this->paypal_user || !$this->paypal_password || !$this->paypal_vendor) { 
  806. return false; 
  807.  
  808. /** 
  809. * Check if the PayPal_PayFlow class has already been established. 
  810. */ 
  811. if (!class_exists('Angelleye_PayPal')) { 
  812. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  813. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  814. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  815.  
  816. /** 
  817. * Create PayPal_PayFlow object. 
  818. */ 
  819. $PayPalConfig = array( 
  820. 'Sandbox' => $this->testmode,  
  821. 'APIUsername' => $this->paypal_user,  
  822. 'APIPassword' => trim($this->paypal_password),  
  823. 'APIVendor' => $this->paypal_vendor,  
  824. 'APIPartner' => $this->paypal_partner,  
  825. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  826. ); 
  827. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  828. $PayPalRequestData = array( 
  829. 'TENDER' => 'C', // C = credit card, P = PayPal 
  830. 'TRXTYPE' => 'C', // S=Sale, A= Auth, C=Credit, D=Delayed Capture, V=Void 
  831. 'ORIGID' => $order->get_transaction_id(),  
  832. 'AMT' => $amount,  
  833. 'CURRENCY' => version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency() 
  834. ); 
  835.  
  836. $PayPalResult = $PayPal->ProcessTransaction($PayPalRequestData); 
  837.  
  838. $PayPalRequest = isset($PayPalResult['RAWREQUEST']) ? $PayPalResult['RAWREQUEST'] : ''; 
  839. $PayPalResponse = isset($PayPalResult['RAWRESPONSE']) ? $PayPalResult['RAWRESPONSE'] : ''; 
  840.  
  841. $this->add_log('Refund Request: ' . print_r($PayPalRequestData, true)); 
  842. $this->add_log('Refund Response: ' . print_r($PayPal->NVPToArray($PayPal->MaskAPIResult($PayPalResponse)), true)); 
  843.  
  844. /** 
  845. * cURL Error Handling #146 
  846. * @since 1.1.8 
  847. */ 
  848.  
  849. AngellEYE_Gateway_Paypal::angelleye_paypal_for_woocommerce_curl_error_handler($PayPalResult, $methos_name = 'Refund Request', $gateway = 'PayPal Payments Pro 2.0 (PayFlow)', $this->error_email_notify); 
  850.  
  851. add_action('angelleye_after_refund', $PayPalResult, $order, $amount, $reason); 
  852. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 0 || $PayPalResult['RESULT'] == 126)) { 
  853.  
  854. $order->add_order_note('Refund Transaction ID:' . $PayPalResult['PNREF']); 
  855.  
  856. $max_remaining_refund = wc_format_decimal($order->get_total() - $order->get_total_refunded()); 
  857. if (!$max_remaining_refund > 0) { 
  858. $order->update_status('refunded'); 
  859.  
  860. if (ob_get_length()) ob_end_clean(); 
  861. return true; 
  862. }else { 
  863. $fc_refund_error = apply_filters('ae_pppf_refund_error_message', $PayPalResult['RESPMSG'], $PayPalResult); 
  864. return new WP_Error('paypal-error', $fc_refund_error); 
  865. return false; 
  866.  
  867. /** 
  868. * Validate the payment form 
  869. * PayFlow - Empty Card Data Validation Problem #220 
  870. * @since 1.1.7.6 
  871. */ 
  872. public function validate_fields() { 
  873.  
  874. if (isset($_POST['wc-paypal_pro_payflow-payment-token']) && 'new' !== $_POST['wc-paypal_pro_payflow-payment-token']) { 
  875. $token_id = wc_clean($_POST['wc-paypal_pro_payflow-payment-token']); 
  876. $token = WC_Payment_Tokens::get($token_id); 
  877. if ($token->get_user_id() !== get_current_user_id()) { 
  878. throw new Exception(__('Error processing checkout. Please try again.', 'paypal-for-woocommerce')); 
  879. } else { 
  880. return true; 
  881. $card_number = isset($_POST['paypal_pro_payflow-card-number']) ? wc_clean($_POST['paypal_pro_payflow-card-number']) : ''; 
  882. $card_cvc = isset($_POST['paypal_pro_payflow-card-cvc']) ? wc_clean($_POST['paypal_pro_payflow-card-cvc']) : ''; 
  883. $card_exp_year = isset($_POST['paypal_pro_payflow_card_expiration_year']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_year']) : ''; 
  884. $card_exp_month = isset($_POST['paypal_pro_payflow_card_expiration_month']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_month']) : ''; 
  885.  
  886.  
  887. // Format values 
  888. $card_number = str_replace(array(' ', '-'), '', $card_number); 
  889.  
  890. if (strlen($card_exp_year) == 4) { 
  891. $card_exp_year = $card_exp_year - 2000; 
  892.  
  893. do_action('before_angelleye_pro_payflow_checkout_validate_fields', $card_number, $card_cvc, $card_exp_month, $card_exp_year); 
  894.  
  895. // Check card security code 
  896.  
  897. if (!ctype_digit($card_cvc)) { 
  898. wc_add_notice(__('Card security code is invalid (only digits are allowed)', 'paypal-for-woocommerce'), "error"); 
  899. return false; 
  900.  
  901. // Check card expiration data 
  902.  
  903. if (!ctype_digit($card_exp_month) || !ctype_digit($card_exp_year) || $card_exp_month > 12 || $card_exp_month < 1 || $card_exp_year < date('y') || $card_exp_year > date('y') + 20) { 
  904. wc_add_notice(__('Card expiration date is invalid', 'paypal-for-woocommerce'), "error"); 
  905. return false; 
  906.  
  907. // Check card number 
  908.  
  909. if (empty($card_number) || !ctype_digit($card_number)) { 
  910. wc_add_notice(__('Card number is invalid', 'paypal-for-woocommerce'), "error"); 
  911. return false; 
  912.  
  913. do_action('after_angelleye_pro_payflow_checkout_validate_fields', $card_number, $card_cvc, $card_exp_month, $card_exp_year); 
  914.  
  915. return true; 
  916.  
  917. public function field_name($name) { 
  918. return ' name="' . esc_attr($this->id . '-' . $name) . '" '; 
  919.  
  920. public function angelleye_paypal_pro_payflow_credit_card_form_fields($default_fields, $current_gateway_id) { 
  921. if ($current_gateway_id == $this->id) { 
  922. $fields = array( 
  923. 'card-number-field' => '<p class="form-row form-row-wide"> 
  924. <label for="' . esc_attr($this->id) . '-card-number">' . __('Card number', 'woocommerce') . ' <span class="required">*</span></label> 
  925. <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') . ' /> 
  926. </p>',  
  927. 'card-expiry-field' => $this->paypal_for_woocommerce_paypal_pro_payflow_credit_card_form_expiration_date_selectbox(),  
  928. '<p class="form-row form-row-last"> 
  929. <label for="' . esc_attr($this->id) . '-card-cvc">' . __('Card Security Code', 'woocommerce') . ' <span class="required">*</span></label> 
  930. <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" /> 
  931. </p>' 
  932. ); 
  933. return $fields; 
  934. } else { 
  935. return $default_fields; 
  936.  
  937. public function angelleye_woocommerce_credit_card_form_start($current_id) { 
  938. if ($this->enable_cardholder_first_last_name && $current_id == $this->id) { 
  939. $fields['card-cardholder-first'] = '<p class="form-row form-row-first"> 
  940. <label for="' . esc_attr($this->id) . '-card-cvc">' . __('Cardholder First Name', 'paypal-for-woocommerce') . '</label> 
  941. <input id="' . esc_attr($this->id) . '-card-cvc" class="input-text wc-credit-card-form-cardholder" type="text" autocomplete="off" placeholder="' . esc_attr__('First Name', 'paypal-for-woocommerce') . '" name="' . $current_id . '-card-cardholder-first' . '" /> 
  942. </p>'; 
  943. $fields['card-cardholder-last'] = '<p class="form-row form-row-last"> 
  944. <label for="' . esc_attr($this->id) . '-card-startdate">' . __('Cardholder Last Name', 'paypal-for-woocommerce') . '</label> 
  945. <input id="' . esc_attr($this->id) . '-card-startdate" class="input-text wc-credit-card-form-cardholder" type="text" autocomplete="off" placeholder="' . __('Last Name', 'paypal-for-woocommerce') . '" name="' . $current_id . '-card-cardholder-last' . '" /> 
  946. </p>'; 
  947.  
  948. foreach ($fields as $field) { 
  949. echo $field; 
  950. public function get_posted_card() { 
  951. try { 
  952. $card_number = isset($_POST['paypal_pro_payflow-card-number']) ? wc_clean($_POST['paypal_pro_payflow-card-number']) : ''; 
  953. $card_cvc = isset($_POST['paypal_pro_payflow-card-cvc']) ? wc_clean($_POST['paypal_pro_payflow-card-cvc']) : ''; 
  954. $card_exp_year = isset($_POST['paypal_pro_payflow_card_expiration_year']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_year']) : ''; 
  955. $card_exp_month = isset($_POST['paypal_pro_payflow_card_expiration_month']) ? wc_clean($_POST['paypal_pro_payflow_card_expiration_month']) : ''; 
  956. $card_number = str_replace(array(' ', '-'), '', $card_number); 
  957. $card_type = AngellEYE_Utility::card_type_from_account_number($card_number); 
  958. if ($card_type == 'amex' && (get_woocommerce_currency() != 'USD' && get_woocommerce_currency() != 'AUD')) { 
  959. throw new Exception(__('Your processor is unable to process the Card Type in the currency requested. Please try another card type', 'paypal-for-woocommerce')); 
  960. if (strlen($card_exp_year) == 4) { 
  961. $card_exp_year = $card_exp_year - 2000; 
  962. $card_exp_month = (int) $card_exp_month; 
  963. if ($card_exp_month < 10) { 
  964. $card_exp_month = '0' . $card_exp_month; 
  965. return (object) array( 
  966. 'number' => $card_number,  
  967. 'type' => '',  
  968. 'cvc' => $card_cvc,  
  969. 'exp_month' => $card_exp_month,  
  970. 'exp_year' => $card_exp_year,  
  971. 'start_month' => '',  
  972. 'start_year' => '' 
  973. ); 
  974. } catch (Exception $ex) { 
  975.  
  976.  
  977.  
  978. public function add_payment_method() { 
  979. $customer_id = get_current_user_id(); 
  980. if (!class_exists('Angelleye_PayPal')) { 
  981. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  982. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  983. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  984. $PayPalConfig = array( 
  985. 'Sandbox' => $this->testmode,  
  986. 'APIUsername' => $this->paypal_user,  
  987. 'APIPassword' => trim($this->paypal_password),  
  988. 'APIVendor' => $this->paypal_vendor,  
  989. 'APIPartner' => $this->paypal_partner,  
  990. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  991. ); 
  992. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  993. $this->validate_fields(); 
  994. $card = $this->get_posted_card(); 
  995.  
  996. $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); 
  997. $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); 
  998. $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); 
  999. $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); 
  1000. $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); 
  1001.  
  1002. $PayPalRequestData = array( 
  1003. 'tender' => 'C',  
  1004. 'trxtype' => 'A',  
  1005. 'acct' => $card->number,  
  1006. 'expdate' => $card->exp_month . $card->exp_year,  
  1007. 'amt' => '0.00',  
  1008. 'currency' => get_woocommerce_currency(),  
  1009. 'cvv2' => $card->cvc,  
  1010. 'orderid' => '',  
  1011. 'orderdesc' => '',  
  1012. 'billtoemail' => '',  
  1013. 'billtophonenum' => '',  
  1014. 'billtofirstname' => $billtofirstname,  
  1015. 'billtomiddlename' => '',  
  1016. 'billtolastname' => $billtolastname,  
  1017. 'billtostreet' => '',  
  1018. 'billtocity' => '',  
  1019. 'billtostate' => $billtostate,  
  1020. 'billtozip' => $billtozip,  
  1021. 'billtocountry' => $billtocountry,  
  1022. 'origid' => '',  
  1023. 'custref' => '',  
  1024. 'custcode' => '',  
  1025. 'custip' => $this->get_user_ip(),  
  1026. 'invnum' => '',  
  1027. 'ponum' => '',  
  1028. 'starttime' => '',  
  1029. 'endtime' => '',  
  1030. 'securetoken' => '',  
  1031. 'partialauth' => '',  
  1032. 'authcode' => '' 
  1033. ); 
  1034. $PayPalResult = $PayPal->ProcessTransaction(apply_filters('angelleye_woocommerce_paypal_express_set_express_checkout_request_args', $PayPalRequestData)); 
  1035. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 0 || $PayPalResult['RESULT'] == 126)) { 
  1036. if ($PayPalResult['RESULT'] == 126) { 
  1037. wc_add_notice(__('The payment was flagged by a fraud filter, please check your PayPal Manager account to review and accept or deny the payment.', 'woocommerce'), 'error'); 
  1038. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1039. exit(); 
  1040. } else { 
  1041. $customer_id = get_current_user_id(); 
  1042. $TRANSACTIONID = $PayPalResult['PNREF']; 
  1043. $this->are_reference_transactions_enabled($TRANSACTIONID); 
  1044. $token = new WC_Payment_Token_CC(); 
  1045. $token->set_user_id($customer_id); 
  1046. $token->set_token($TRANSACTIONID); 
  1047. $token->set_gateway_id($this->id); 
  1048. $token->set_card_type(AngellEYE_Utility::card_type_from_account_number($PayPalRequestData['acct'])); 
  1049. $token->set_last4(substr($PayPalRequestData['acct'], -4)); 
  1050. $token->set_expiry_month( substr( $PayPalRequestData['expdate'], 0, 2 ) ); 
  1051. $expiry_year = substr( $PayPalRequestData['expdate'], 2, 3 ); 
  1052. if ( strlen( $expiry_year ) == 2 ) { 
  1053. $expiry_year = $expiry_year + 2000; 
  1054. $token->set_expiry_year( $expiry_year ); 
  1055. $save_result = $token->save(); 
  1056. if ($save_result) { 
  1057. return array( 
  1058. 'result' => 'success',  
  1059. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  1060. ); 
  1061. } else { 
  1062. wc_add_notice(__($PayPalResult['RESPMSG'], 'woocommerce'), 'error'); 
  1063. wp_redirect(wc_get_account_endpoint_url('payment-methods')); 
  1064. exit(); 
  1065. public function process_subscription_payment($order, $amount) { 
  1066. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  1067. if (!class_exists('Angelleye_PayPal')) { 
  1068. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  1069. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  1070. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  1071. $PayPalConfig = array( 
  1072. 'Sandbox' => $this->testmode,  
  1073. 'APIUsername' => $this->paypal_user,  
  1074. 'APIPassword' => trim($this->paypal_password),  
  1075. 'APIVendor' => $this->paypal_vendor,  
  1076. 'APIPartner' => $this->paypal_partner,  
  1077. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  1078. ); 
  1079. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  1080. try { 
  1081.  
  1082. if(!empty($_POST['paypal_pro_payflow-card-cardholder-first'])) { 
  1083. $firstname = wc_clean($_POST['paypal_pro_payflow-card-cardholder-first']); 
  1084. } else { 
  1085. $firstname = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name(); 
  1086. }  
  1087.  
  1088. if(!empty($_POST['paypal_pro_payflow-card-cardholder-last'])) { 
  1089. $lastname = wc_clean($_POST['paypal_pro_payflow-card-cardholder-last']); 
  1090. } else { 
  1091. $lastname = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name(); 
  1092.  
  1093. $billing_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_1 : $order->get_billing_address_1(); 
  1094. $billing_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_address_2 : $order->get_billing_address_2(); 
  1095. $billing_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_city : $order->get_billing_city(); 
  1096. $billing_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_postcode : $order->get_billing_postcode(); 
  1097. $billing_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_country : $order->get_billing_country(); 
  1098. $billing_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_state : $order->get_billing_state(); 
  1099. $billing_email = version_compare( WC_VERSION, '3.0', '<' ) ? $billing_email : $order->get_billing_email(); 
  1100.  
  1101. $customer_note = $order->customer_note ? substr(preg_replace("/[^A-Za-z0-9 ]/", "", $order->customer_note), 0, 256) : ''; 
  1102. $PayPalRequestData = array( 
  1103. 'tender' => 'C', // Required. The method of payment. Values are: A = ACH, C = Credit Card, D = Pinless Debit, K = Telecheck, P = PayPal 
  1104. 'trxtype' => ($this->payment_action == 'Authorization' || $order->get_total() == 0 ) ? 'A' : 'S', // Required. Indicates the type of transaction to perform. Values are: A = Authorization, B = Balance Inquiry, C = Credit, D = Delayed Capture, F = Voice Authorization, I = Inquiry, L = Data Upload, N = Duplicate Transaction, S = Sale, V = Void 
  1105. 'amt' => AngellEYE_Gateway_Paypal::number_format($order->get_total()), // Required. Amount of the transaction. Must have 2 decimal places. 
  1106. 'currency' => get_woocommerce_currency(), // 
  1107. 'comment1' => apply_filters('ae_pppf_custom_parameter', $customer_note, $order), // Merchant-defined value for reporting and auditing purposes. 128 char max 
  1108. 'comment2' => apply_filters('ae_pppf_comment2_parameter', '', $order), // Merchant-defined value for reporting and auditing purposes. 128 char max 
  1109. 'recurring' => '', // Identifies the transaction as recurring. One of the following values: Y = transaction is recurring, N = transaction is not recurring. 
  1110. 'swipe' => '', // Required for card-present transactions. Used to pass either Track 1 or Track 2, but not both. 
  1111. 'orderid' => $this->invoice_id_prefix . preg_replace("/[^a-zA-Z0-9]/", "", $order->get_order_number()), // Checks for duplicate order. If you pass orderid in a request and pass it again in the future the response returns DUPLICATE=2 along with the orderid 
  1112. 'orderdesc' => 'Order ' . $order->get_order_number() . ' on ' . get_bloginfo('name'), // 
  1113. 'billtoemail' => $billing_email, // Account holder's email address. 
  1114. 'billtophonenum' => '', // Account holder's phone number. 
  1115. 'billtostreet' => $billing_address_1 . ' ' . $billing_address_2, // The cardholder's street address (number and street name). 150 char max 
  1116. 'billtocity' => $billing_city, // Bill to city. 45 char max 
  1117. 'billtostate' => $billing_state, // Bill to state. 
  1118. 'billtozip' => $billing_postcode, // Account holder's 5 to 9 digit postal code. 9 char max. No dashes, spaces, or non-numeric characters 
  1119. 'billtocountry' => $billing_country, // Bill to Country. 3 letter country code. 
  1120. 'origid' => '', // Required by some transaction types. ID of the original transaction referenced. The PNREF parameter returns this ID, and it appears as the Transaction ID in PayPal Manager reports. 
  1121. 'custref' => '', // 
  1122. 'custcode' => '', // 
  1123. 'custip' => $this->get_user_ip(), // 
  1124. 'invnum' => $this->invoice_id_prefix . str_replace("#", "", $order->get_order_number()), // 
  1125. 'ponum' => '', // 
  1126. 'starttime' => '', // For inquiry transaction when using CUSTREF to specify the transaction. 
  1127. 'endtime' => '', // For inquiry transaction when using CUSTREF to specify the transaction. 
  1128. 'securetoken' => '', // Required if using secure tokens. A value the Payflow server created upon your request for storing transaction data. 32 char 
  1129. 'partialauth' => '', // Required for partial authorizations. Set to Y to submit a partial auth. 
  1130. 'authcode' => '' // Rrequired for voice authorizations. Returned only for approved voice authorization transactions. AUTHCODE is the approval code received over the phone from the processing network. 6 char max 
  1131. ); 
  1132. /** 
  1133. * Shipping info 
  1134. */ 
  1135.  
  1136. $shipping_first_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_first_name : $order->get_shipping_first_name(); 
  1137. $shipping_last_name = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_last_name : $order->get_shipping_last_name(); 
  1138. $shipping_address_1 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_1 : $order->get_shipping_address_1(); 
  1139. $shipping_address_2 = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_address_2 : $order->get_shipping_address_2(); 
  1140. $shipping_city = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_city : $order->get_shipping_city(); 
  1141. $shipping_postcode = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_postcode : $order->get_shipping_postcode(); 
  1142. $shipping_country = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_country : $order->get_shipping_country(); 
  1143. $shipping_state = version_compare( WC_VERSION, '3.0', '<' ) ? $order->shipping_state : $order->get_shipping_state(); 
  1144.  
  1145. if ($shipping_address_1) { 
  1146. $PayPalRequestData['SHIPTOFIRSTNAME'] = $shipping_first_name; 
  1147. $PayPalRequestData['SHIPTOLASTNAME'] = $shipping_last_name; 
  1148. $PayPalRequestData['SHIPTOSTREET'] = $shipping_address_1 . ' ' . $shipping_address_2; 
  1149. $PayPalRequestData['SHIPTOCITY'] = $shipping_city; 
  1150. $PayPalRequestData['SHIPTOSTATE'] = $shipping_state; 
  1151. $PayPalRequestData['SHIPTOCOUNTRY'] = $shipping_country; 
  1152. $PayPalRequestData['SHIPTOZIP'] = $shipping_postcode; 
  1153. $PaymentData = $this->calculation_angelleye->order_calculation($order_id); 
  1154. $OrderItems = array(); 
  1155. if ($this->send_items) { 
  1156. $item_loop = 0; 
  1157. foreach ($PaymentData['order_items'] as $_item) { 
  1158. $Item['L_NUMBER' . $item_loop] = $_item['number']; 
  1159. $Item['L_NAME' . $item_loop] = $_item['name']; 
  1160. $Item['L_COST' . $item_loop] = $_item['amt']; 
  1161. $Item['L_QTY' . $item_loop] = $_item['qty']; 
  1162. if ($_item['number']) { 
  1163. $Item['L_SKU' . $item_loop] = $_item['number']; 
  1164. $OrderItems = array_merge($OrderItems, $Item); 
  1165. $item_loop++; 
  1166. /** 
  1167. * Shipping/tax/item amount 
  1168. */ 
  1169. $PayPalRequestData['taxamt'] = $PaymentData['taxamt']; 
  1170. $PayPalRequestData['freightamt'] = $PaymentData['shippingamt']; 
  1171. $PayPalRequestData['ITEMAMT'] = $PaymentData['itemamt']; 
  1172. if ($this->send_items) { 
  1173. $PayPalRequestData = array_merge($PayPalRequestData, $OrderItems); 
  1174. if (!empty($order->subscription_renewal)) { 
  1175. $PayPalRequestData['origid'] = get_post_meta($order_id, '_payment_tokens_id', true); 
  1176. $PayPalResult = $PayPal->ProcessTransaction($PayPalRequestData); 
  1177.  
  1178. $this->add_log('PayFlow Endpoint: ' . $PayPal->APIEndPoint); 
  1179. $this->add_log('PayFlow Response: ' . print_r($PayPalResult, true)); 
  1180.  
  1181. if (empty($PayPalResult['RAWRESPONSE'])) { 
  1182. $fc_empty_response = apply_filters('ae_pppf_paypal_response_empty_message', __('Empty PayPal response.', 'paypal-for-woocommerce'), $PayPalResult); 
  1183. throw new Exception($fc_empty_response); 
  1184. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 0 || $PayPalResult['RESULT'] == 126)) { 
  1185. if ($PayPalResult['RESULT'] == 126) { 
  1186. $order->add_order_note($PayPalResult['RESPMSG']); 
  1187. $order->add_order_note($PayPalResult['PREFPSMSG']); 
  1188. $order->add_order_note("The payment was flagged by a fraud filter, please check your PayPal Manager account to review and accept or deny the payment."); 
  1189. } else { 
  1190. if (isset($PayPalResult['PPREF']) && !empty($PayPalResult['PPREF'])) { 
  1191. add_post_meta($order_id, 'PPREF', $PayPalResult['PPREF']); 
  1192. $order->add_order_note(sprintf(__('PayPal Pro payment completed (PNREF: %s) (PPREF: %s)', 'paypal-for-woocommerce'), $PayPalResult['PNREF'], $PayPalResult['PPREF'])); 
  1193. } else { 
  1194. $order->add_order_note(sprintf(__('PayPal Pro payment completed (PNREF: %s)', 'paypal-for-woocommerce'), $PayPalResult['PNREF'])); 
  1195. /** Checkout Note */ 
  1196. if (isset($_POST) && !empty($_POST['order_comments'])) { 
  1197. $checkout_note = array( 
  1198. 'ID' => $order_id,  
  1199. 'post_excerpt' => $_POST['order_comments'],  
  1200. ); 
  1201. wp_update_post($checkout_note); 
  1202. /** 
  1203. * Add order notes for AVS result 
  1204. */ 
  1205. $avs_address_response_code = isset($PayPalResult['AVSADDR']) ? $PayPalResult['AVSADDR'] : ''; 
  1206. $avs_zip_response_code = isset($PayPalResult['AVSZIP']) ? $PayPalResult['AVSZIP'] : ''; 
  1207. $avs_response_order_note = __('Address Verification Result', 'paypal-for-woocommerce'); 
  1208. $avs_response_order_note .= "\n"; 
  1209. $avs_response_order_note .= sprintf(__('Address Match: %s', 'paypal-for-woocommerce'), $avs_address_response_code); 
  1210. $avs_response_order_note .= "\n"; 
  1211. $avs_response_order_note .= sprintf(__('Postal Match: %s', 'paypal-for-woocommerce'), $avs_zip_response_code); 
  1212. $order->add_order_note($avs_response_order_note); 
  1213. /** 
  1214. * Add order notes for CVV2 result 
  1215. */ 
  1216. $cvv2_response_code = isset($PayPalResult['CVV2MATCH']) ? $PayPalResult['CVV2MATCH'] : ''; 
  1217. $cvv2_response_order_note = __('Card Security Code Result', 'paypal-for-woocommerce'); 
  1218. $cvv2_response_order_note .= "\n"; 
  1219. $cvv2_response_order_note .= sprintf(__('CVV2 Match: %s', 'paypal-for-woocommerce'), $cvv2_response_code); 
  1220. $order->add_order_note($cvv2_response_order_note); 
  1221. $order->payment_complete($PayPalResult['PNREF']); 
  1222. $this->save_payment_token($order, $PayPalResult['PNREF']); 
  1223. $this->are_reference_transactions_enabled($PayPalResult['PNREF']); 
  1224. if (!empty($order->subscription_renewal)) { 
  1225. return true; 
  1226. } else { 
  1227. $order->update_status('failed', __('PayPal Pro payment failed. Payment was rejected due to an error: ', 'paypal-for-woocommerce') . '(' . $PayPalResult['RESULT'] . ') ' . '"' . $PayPalResult['RESPMSG'] . '"'); 
  1228. if ($this->error_email_notify) { 
  1229. $admin_email = get_option("admin_email"); 
  1230. $message = __("PayFlow API call failed.", "paypal-for-woocommerce") . "\n\n"; 
  1231. $message .= __('Error Code: ', 'paypal-for-woocommerce') . $PayPalResult['RESULT'] . "\n"; 
  1232. $message .= __('Detailed Error Message: ', 'paypal-for-woocommerce') . $PayPalResult['RESPMSG']; 
  1233. $message .= isset($PayPalResult['PREFPSMSG']) && $PayPalResult['PREFPSMSG'] != '' ? ' - ' . $PayPalResult['PREFPSMSG'] . "\n" : "\n"; 
  1234. $message .= __('User IP: ', 'paypal-for-woocommerce') . $this->get_user_ip() . "\n"; 
  1235. $message .= __('Order ID: ') . $order_id . "\n"; 
  1236. $message .= __('Customer Name: ') . $firstname . ' ' . $lastname . "\n"; 
  1237. $message .= __('Customer Email: ') . $billing_email . "\n"; 
  1238. $message = apply_filters('ae_pppf_error_email_message', $message); 
  1239. $subject = apply_filters('ae_pppf_error_email_subject', "PayPal Pro Error Notification"); 
  1240. wp_mail($admin_email, $subject, $message); 
  1241. return; 
  1242. } catch (Exception $e) { 
  1243. if ($order->has_status(array('pending', 'failed'))) { 
  1244. $this->send_failed_order_email($order_id); 
  1245. return; 
  1246.  
  1247. public function are_reference_transactions_enabled($token_id) { 
  1248. if ($this->supports('tokenization') && class_exists('WC_Subscriptions_Order')) { 
  1249. $are_reference_transactions_enabled = get_option('are_reference_transactions_enabled', 'no'); 
  1250. if ($are_reference_transactions_enabled == 'no') { 
  1251. $customer_id = get_current_user_id(); 
  1252. if (!class_exists('Angelleye_PayPal')) { 
  1253. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  1254. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  1255. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  1256. $PayPalConfig = array( 
  1257. 'Sandbox' => $this->testmode,  
  1258. 'APIUsername' => $this->paypal_user,  
  1259. 'APIPassword' => trim($this->paypal_password),  
  1260. 'APIVendor' => $this->paypal_vendor,  
  1261. 'APIPartner' => $this->paypal_partner,  
  1262. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  1263. ); 
  1264. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  1265. $this->validate_fields(); 
  1266. $card = $this->get_posted_card(); 
  1267. $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); 
  1268. $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); 
  1269. $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); 
  1270. $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); 
  1271. $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); 
  1272. $PayPalRequestData = array( 
  1273. 'tender' => 'C',  
  1274. 'trxtype' => 'A',  
  1275. 'acct' => '',  
  1276. 'expdate' => '',  
  1277. 'amt' => '0.00',  
  1278. 'currency' => get_woocommerce_currency(),  
  1279. 'cvv2' => '',  
  1280. 'orderid' => '',  
  1281. 'orderdesc' => '',  
  1282. 'billtoemail' => '',  
  1283. 'billtophonenum' => '',  
  1284. 'billtofirstname' => $billtofirstname,  
  1285. 'billtomiddlename' => '',  
  1286. 'billtolastname' => $billtolastname,  
  1287. 'billtostreet' => '',  
  1288. 'billtocity' => '',  
  1289. 'billtostate' => $billtostate,  
  1290. 'billtozip' => $billtozip,  
  1291. 'billtocountry' => $billtocountry,  
  1292. 'origid' => $token_id,  
  1293. 'custref' => '',  
  1294. 'custcode' => '',  
  1295. 'custip' => $this->get_user_ip(),  
  1296. 'invnum' => '',  
  1297. 'ponum' => '',  
  1298. 'starttime' => '',  
  1299. 'endtime' => '',  
  1300. 'securetoken' => '',  
  1301. 'partialauth' => '',  
  1302. 'authcode' => '' 
  1303. ); 
  1304. $PayPalResult = $PayPal->ProcessTransaction($PayPalRequestData); 
  1305. if (isset($PayPalResult['RESULT']) && ($PayPalResult['RESULT'] == 117)) { 
  1306. $admin_email = get_option("admin_email"); 
  1307. $message = __("PayPal Reference Transactions are not enabled on your account, some subscription management features are not enabled", "paypal-for-woocommerce") . "\n\n"; 
  1308. $message .= __("PayFlow API call failed.", "paypal-for-woocommerce") . "\n\n"; 
  1309. $message .= __('Error Code: ', 'paypal-for-woocommerce') . $PayPalResult['RESULT'] . "\n"; 
  1310. $message .= __('Detailed Error Message: ', 'paypal-for-woocommerce') . $PayPalResult['RESPMSG']; 
  1311. $message .= isset($PayPalResult['PREFPSMSG']) && $PayPalResult['PREFPSMSG'] != '' ? ' - ' . $PayPalResult['PREFPSMSG'] . "\n" : "\n"; 
  1312. $message .= __('User IP: ', 'paypal-for-woocommerce') . $this->get_user_ip() . "\n"; 
  1313. $message = apply_filters('ae_pppf_error_email_message', $message); 
  1314. $subject = apply_filters('ae_pppf_error_email_subject', "PayPal Payments Pro (PayFlow) Error Notification"); 
  1315. wp_mail($admin_email, $subject, $message); 
  1316. return false; 
  1317. } else { 
  1318. update_option('are_reference_transactions_enabled', 'yes'); 
  1319. public function send_failed_order_email($order_id) { 
  1320. $emails = WC()->mailer()->get_emails(); 
  1321. if (!empty($emails) && !empty($order_id)) { 
  1322. $emails['WC_Email_Failed_Order']->trigger($order_id); 
  1323.  
  1324. public function save_payment_token($order, $payment_tokens_id) { 
  1325. // Store source in the order 
  1326. if (!empty($payment_tokens_id)) { 
  1327. update_post_meta($order->id, '_payment_tokens_id', $payment_tokens_id); 
  1328. return $settings; 
  1329.  
  1330.  
  1331. public function angelleye_paypal_pro_payflow_encrypt_gateway_api($settings) { 
  1332. if( !empty($settings['sandbox_paypal_partner'])) { 
  1333. $paypal_partner = $settings['sandbox_paypal_partner']; 
  1334. } else { 
  1335. $paypal_partner = $settings['paypal_partner']; 
  1336. if(strlen($paypal_partner) > 28 ) { 
  1337. return $settings; 
  1338.  
  1339. if( !empty($settings['is_encrypt']) ) { 
  1340. $gateway_settings_keys = array('sandbox_paypal_vendor', 'sandbox_paypal_password', 'sandbox_paypal_user', 'sandbox_paypal_partner', 'paypal_vendor', 'paypal_password', 'paypal_user', 'paypal_partner'); 
  1341. foreach ($gateway_settings_keys as $gateway_settings_key => $gateway_settings_value) { 
  1342. if( !empty( $settings[$gateway_settings_value]) ) { 
  1343. $settings[$gateway_settings_value] = AngellEYE_Utility::crypting($settings[$gateway_settings_value], $action = 'e'); 
  1344. return $settings; 
  1345.  
  1346. public function angelleye_paypal_pro_payflow_email_instructions($order, $sent_to_admin, $plain_text = false) { 
  1347. $payment_method = version_compare( WC_VERSION, '3.0', '<' ) ? $order->payment_method : $order->get_payment_method(); 
  1348. if ( $sent_to_admin && 'paypal_pro_payflow' === $payment_method ) { 
  1349. // Store source in the order 
  1350. if (!class_exists('Angelleye_PayPal')) { 
  1351. require_once('lib/angelleye/paypal-php-library/includes/paypal.class.php'); 
  1352. if (!class_exists('Angelleye_PayPal_PayFlow')) { 
  1353. require_once('lib/angelleye/paypal-php-library/includes/paypal.payflow.class.php'); 
  1354. $PayPalConfig = array( 
  1355. 'Sandbox' => $this->testmode,  
  1356. 'APIUsername' => $this->paypal_user,  
  1357. 'APIPassword' => trim($this->paypal_password),  
  1358. 'APIVendor' => $this->paypal_vendor,  
  1359. 'APIPartner' => $this->paypal_partner,  
  1360. 'Force_tls_one_point_two' => $this->Force_tls_one_point_two 
  1361. ); 
  1362. $PayPal = new Angelleye_PayPal_PayFlow($PayPalConfig); 
  1363. $old_wc = version_compare( WC_VERSION, '3.0', '<' ); 
  1364. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  1365. $cvvmatch = $old_wc ? get_post_meta( $order->id, '_CVV2MATCH', true ) : get_post_meta($order->get_id(), '_CVV2MATCH', true); 
  1366. if ( ! empty( $cvvmatch ) ) { 
  1367. $cvv2_response_message = $PayPal->GetCVV2CodeMessage($cvvmatch); 
  1368. echo '<h2 class="wc-cvv2-details-heading">' . __( 'Card Security Code Details', 'paypal-for-woocommerce' ) . '</h2>' . PHP_EOL; 
  1369. echo '<ul class="wc-cvv2-details order_details cvv2_details">' . PHP_EOL; 
  1370. $cvv_details_fields = apply_filters( 'angelleye_cvv2_details_fields', array( 
  1371. 'cvv2_response_code'=> array( 
  1372. 'label' => __( 'Card Security Code', 'paypal-for-woocommerce' ),  
  1373. 'value' => $cvvmatch 
  1374. ),  
  1375. 'cvv2_response_message' => array( 
  1376. 'label' => __( 'Card Security Message', 'paypal-for-woocommerce' ),  
  1377. 'value' => $cvv2_response_message 
  1378. ), $order_id ); 
  1379. foreach ( $cvv_details_fields as $field_key => $field ) { 
  1380. if ( ! empty( $field['value'] ) ) { 
  1381. echo '<li class="' . esc_attr( $field_key ) . '">' . esc_attr( $field['label'] ) . ': <strong>' . wptexturize( $field['value'] ) . '</strong></li>' . PHP_EOL; 
  1382. echo '</ul>'; 
  1383.  
  1384. $avscode = $old_wc ? get_post_meta( $order->id, '_AVSADDR', true ) : get_post_meta($order->get_id(), '_AVSADDR', true); 
  1385. if ( ! empty( $avscode ) ) { 
  1386. $avs_response_message = $PayPal->GetAVSCodeMessage($avscode); 
  1387. echo '<h2 class="wc-avs-details-heading">' . __( 'Address Verification Details', 'paypal-for-woocommerce' ) . '</h2>' . PHP_EOL; 
  1388. echo '<ul class="wc-avs-details order_details avs_details">' . PHP_EOL; 
  1389. $avs_details_fields = apply_filters( 'angelleye_avs_details_fields', array( 
  1390. 'avs_response_code'=> array( 
  1391. 'label' => __( 'AVS Response Code', 'paypal-for-woocommerce' ),  
  1392. 'value' => $avscode 
  1393. ),  
  1394. 'avs_response_message' => array( 
  1395. 'label' => __( 'AVS Response Message', 'paypal-for-woocommerce' ),  
  1396. 'value' => $avs_response_message 
  1397. ), $order_id ); 
  1398. foreach ( $avs_details_fields as $field_key => $field ) { 
  1399. if ( ! empty( $field['value'] ) ) { 
  1400. echo '<li class="' . esc_attr( $field_key ) . '">' . esc_attr( $field['label'] ) . ': <strong>' . wptexturize( $field['value'] ) . '</strong></li>' . PHP_EOL; 
  1401. echo '</ul>'; 
  1402.