PluginProbe ʕ •ᴥ•ʔ
FraudLabs Pro for WooCommerce / 2.24.2
FraudLabs Pro for WooCommerce v2.24.2
2.24.2 2.24.1 2.24.0 trunk 2.10.0 2.10.1 2.10.10 2.10.11 2.10.12 2.10.13 2.10.14 2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.10.8 2.10.9 2.11.0 2.11.1 2.11.10 2.11.11 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6 2.13.0 2.13.1 2.13.10 2.13.2 2.13.3 2.13.4 2.13.5 2.13.6 2.13.7 2.13.8 2.13.9 2.14.0 2.14.1 2.14.10 2.14.11 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 2.14.7 2.14.8 2.14.9 2.15.0 2.16.0 2.16.1 2.16.10 2.16.11 2.16.12 2.16.13 2.16.14 2.16.15 2.16.16 2.16.17 2.16.18 2.16.19 2.16.2 2.16.3 2.16.4 2.16.5 2.16.6 2.16.7 2.16.8 2.16.9 2.17.0 2.17.1 2.17.2 2.17.3 2.17.4 2.17.5 2.17.6 2.17.7 2.17.8 2.18.0 2.18.1 2.18.2 2.18.3 2.18.4 2.18.5 2.19.0 2.19.1 2.19.2 2.19.3 2.20.0 2.20.1 2.20.2 2.20.3 2.21.0 2.21.1 2.22.0 2.22.1 2.22.10 2.22.11 2.22.12 2.22.13 2.22.14 2.22.15 2.22.2 2.22.3 2.22.4 2.22.5 2.22.6 2.22.7 2.22.8 2.22.9 2.23.0 2.23.1 2.23.2 2.23.3 2.23.4 2.23.5 2.23.6 2.23.7 2.8.17 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5
fraudlabs-pro-for-woocommerce / includes / class.wc-fraudlabspro.php
fraudlabs-pro-for-woocommerce / includes Last commit date
class.wc-fraudlabspro.php 1 week ago flp-callback.php 1 year ago
class.wc-fraudlabspro.php
3287 lines
1 <?php
2 defined( 'DS' ) or define( 'DS', DIRECTORY_SEPARATOR );
3 define( 'FRAUDLABS_PRO_ROOT', dirname( __DIR__ ) . DS );
4
5 require_once FRAUDLABS_PRO_ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
6
7 if ( ! class_exists( 'WC_FraudLabs_Pro' ) ) :
8
9 class WC_FraudLabs_Pro {
10 protected static $instance;
11
12 private $order;
13 private $namespace;
14 private $enabled;
15 private $api_key;
16 public $validation_sequence;
17 private $flp_advanced_velocity;
18 private $approve_status;
19 private $review_status;
20 private $reject_status;
21 private $db_err_status;
22 private $change_status_auto;
23 private $reject_failed_order;
24 private $fraud_message;
25 private $real_ip_detect;
26 private $test_ip;
27 private $notification_approve;
28 private $notification_review;
29 private $notification_reject;
30 private $expand_report;
31 private $debug_log;
32 private $debug_log_path;
33
34 public static function get_instance() {
35 if ( is_null( self::$instance ) ) {
36 self::$instance = new self;
37 }
38
39 return self::$instance;
40 }
41
42
43 public function __construct() {
44 // Do not proceed if WooCommerce is not installed.
45 if ( ! function_exists( 'WC' ) ) {
46 $this->write_debug_log( 'WooCommerce plugin is not installed. FraudLabs Pro validation will not be performed.' );
47 return;
48 }
49
50 $this->namespace = 'woocommerce-fraudlabs-pro';
51 $this->enabled = $this->get_setting( 'enabled' );
52 $this->api_key = $this->get_setting( 'api_key' );
53 $this->validation_sequence = ( $this->get_setting( 'validation_sequence' ) ) ? $this->get_setting( 'validation_sequence' ) : 'after';
54 $this->flp_advanced_velocity = $this->get_setting( 'flp_advanced_velocity' );
55 $this->approve_status = $this->get_setting( 'approve_status' );
56 $this->review_status = ( $this->get_setting( 'review_status' ) ) ? $this->get_setting( 'review_status' ) : '';
57 $this->reject_status = ( $this->get_setting( 'reject_status' ) ) ? $this->get_setting( 'reject_status' ) : '';
58 $this->db_err_status = ( $this->get_setting( 'db_err_status' ) ) ? $this->get_setting( 'db_err_status' ) : '';
59 $this->change_status_auto = $this->get_setting( 'change_status_auto' );
60 $this->reject_failed_order = $this->get_setting( 'reject_failed_order' );
61 $this->fraud_message = $this->get_setting( 'fraud_message' );
62 $this->real_ip_detect = ( $this->get_setting( 'real_ip_detect' ) ) ? $this->get_setting( 'real_ip_detect' ) : '';
63 $this->test_ip = $this->get_setting( 'test_ip' );
64 $this->notification_approve = $this->get_setting( 'notification_approve' );
65 $this->notification_review = $this->get_setting( 'notification_review' );
66 $this->notification_reject = $this->get_setting( 'notification_reject' );
67 $this->expand_report = $this->get_setting( 'expand_report' );
68 $this->debug_log = $this->get_setting( 'debug_log' );
69 $this->debug_log_path = $this->get_setting( 'debug_log_path' );
70
71 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
72 add_action( 'admin_footer_text', array( $this, 'admin_footer_text' ) );
73 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
74 add_action( 'admin_notices', array( $this, 'admin_notices' ) );
75 add_action( 'wp_ajax_fraudlabspro_woocommerce_submit_feedback', array( $this, 'submit_feedback' ) );
76 add_action( 'wp_ajax_fraudlabspro_woocommerce_validate_api_key', array( $this, 'validate_api_key' ) );
77 add_action( 'wp_loaded', array( $this, 'wc_flp_callback' ) );
78 add_action( 'wp_footer', array( $this, 'javascript_agent' ) );
79
80 // Hooks for WooCommerce
81 add_filter( 'manage_shop_order_posts_columns', array( $this, 'add_column' ), 11 );
82 add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_column' ), 3 );
83 add_filter( 'manage_woocommerce_page_wc-orders_columns', array( $this, 'add_column_hpos' ), 11 );
84 add_action( 'woocommerce_shop_order_list_table_custom_column', array( $this, 'render_column_hpos' ), 10, 2 );
85 add_action( 'woocommerce_admin_order_data_after_billing_address', array( $this, 'render_fraud_report' ) );
86 add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'store_checkout_order_processed' ), 99, 3 );
87 add_action( 'woocommerce_after_checkout_form', array( $this, 'javascript_agent' ) );
88 add_action( 'woocommerce_checkout_order_processed', array( $this, 'checkout_order_processed' ), 99, 3 );
89 add_action( 'woocommerce_order_status_changed', array( $this, 'order_status_changed' ), 999, 3 );
90 add_action( 'woocommerce_order_status_completed', array( $this, 'order_status_completed' ) );
91 add_action( 'woocommerce_order_status_cancelled', array( $this, 'order_status_cancelled' ) );
92 add_action( 'woocommerce_pre_payment_complete', array( $this, 'pre_payment_complete' ) );
93 add_action( 'woocommerce_payment_complete', array( $this, 'payment_complete' ) );
94 }
95
96
97 /**
98 * Validate the order before payment gateway.
99 */
100 public function store_checkout_order_processed( $order ) {
101 // Collect IP information before the payment gateway
102 $ip_x_sucuri_before = $ip_incap_before = $ip_http_cf_connecting_before = $ip_x_forwarded_for_before = $ip_x_real_before = $ip_http_client_before = $ip_http_forwarded_before = $ip_x_forwarded_before ='::1';
103
104 if ( isset( $_SERVER['HTTP_X_SUCURI_CLIENTIP'] ) && filter_var( $_SERVER['HTTP_X_SUCURI_CLIENTIP'], FILTER_VALIDATE_IP ) ) {
105 $ip_x_sucuri_before = $_SERVER['HTTP_X_SUCURI_CLIENTIP'];
106 }
107
108 if( isset( $_SERVER['HTTP_INCAP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_INCAP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
109 $ip_incap_before = $_SERVER['HTTP_INCAP_CLIENT_IP'];
110 }
111
112 if( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) && filter_var( $_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP ) ) {
113 $ip_http_cf_connecting_before = $_SERVER['HTTP_CF_CONNECTING_IP'];
114 }
115
116 if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
117 $ip_x_real_before = $_SERVER['HTTP_X_REAL_IP'];
118 }
119
120 if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
121 $xip = trim(current(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])));
122
123 if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
124 $ip_x_forwarded_for_before = $xip;
125 }
126 }
127
128 if( isset( $_SERVER['HTTP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
129 $ip_http_client_before = $_SERVER['HTTP_CLIENT_IP'];
130 }
131
132 if( isset( $_SERVER['HTTP_FORWARDED'] ) && filter_var( $_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP ) ) {
133 $ip_http_forwarded_before = $_SERVER['HTTP_FORWARDED'];
134 }
135
136 if( isset( $_SERVER['HTTP_X_FORWARDED'] ) && filter_var( $_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP ) ) {
137 $ip_x_forwarded_before = $_SERVER['HTTP_X_FORWARDED'];
138 }
139
140 $ip_remote_addr_before = $_SERVER['REMOTE_ADDR'];
141 $flp_checksum_before = ( isset( $_COOKIE['flp_checksum'] ) ) ? $_COOKIE['flp_checksum'] : '';
142 $flp_device_before = ( isset( $_COOKIE['flp_device'] ) ) ? $_COOKIE['flp_device'] : '';
143
144 $flpIP = [
145 'ip_x_sucuri_before' => $ip_x_sucuri_before,
146 'ip_incap_before' => $ip_incap_before,
147 'ip_http_cf_connecting_before' => $ip_http_cf_connecting_before,
148 'ip_x_real_before' => $ip_x_real_before,
149 'ip_x_forwarded_for_before' => $ip_x_forwarded_for_before,
150 'ip_http_client_before' => $ip_http_client_before,
151 'ip_http_forwarded_before' => $ip_http_forwarded_before,
152 'ip_x_forwarded_before' => $ip_x_forwarded_before,
153 'ip_remote_addr_before' => $ip_remote_addr_before,
154 'flp_checksum_before' => $flp_checksum_before,
155 'flp_device_before' => $flp_device_before,
156 ];
157
158 if ( $this->validation_sequence !== 'before' ) {
159 return;
160 }
161
162 if ( ! $order instanceof \WC_Order ) {
163 return;
164 }
165
166 $this->order = $order;
167 $order_id = $this->order->get_id();
168 add_post_meta( $order_id, '_fraudlabspro_ip_before', $flpIP );
169 $table_name = $this->create_flpwc_table();
170 $this->add_flpwc_data($table_name, $order_id, '_fraudlabspro_ip_before', $flpIP);
171 $this->write_debug_log( 'Store checkout order processed for Order ' . $order_id . '.');
172
173 if ( $this->validate_order() === false ) {
174 wc_add_notice( ( !empty( $this->fraud_message ) ) ? $this->fraud_message : 'This order ' . $order_id . ' failed our fraud validation. Please contact us for more details.', 'error' );
175
176 global $woocommerce;
177 $woocommerce->cart->empty_cart();
178
179 if ( is_ajax() ) {
180 wp_send_json( array(
181 'result' => 'success',
182 'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', wc_get_cart_url(), $this->order ),
183 ) );
184 } else {
185 wp_safe_redirect(
186 apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', wc_get_cart_url(), $this->order )
187 );
188 exit;
189 }
190 }
191 }
192
193 public function checkout_order_processed( $order_id, $posted_data, $order ) {
194 // Collect IP information before the payment gateway
195 $ip_x_sucuri_before = $ip_incap_before = $ip_http_cf_connecting_before = $ip_x_forwarded_for_before = $ip_x_real_before = $ip_http_client_before = $ip_http_forwarded_before = $ip_x_forwarded_before ='::1';
196
197 if ( isset( $_SERVER['HTTP_X_SUCURI_CLIENTIP'] ) && filter_var( $_SERVER['HTTP_X_SUCURI_CLIENTIP'], FILTER_VALIDATE_IP ) ) {
198 $ip_x_sucuri_before = $_SERVER['HTTP_X_SUCURI_CLIENTIP'];
199 }
200
201 if( isset( $_SERVER['HTTP_INCAP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_INCAP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
202 $ip_incap_before = $_SERVER['HTTP_INCAP_CLIENT_IP'];
203 }
204
205 if( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) && filter_var( $_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP ) ) {
206 $ip_http_cf_connecting_before = $_SERVER['HTTP_CF_CONNECTING_IP'];
207 }
208
209 if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
210 $ip_x_real_before = $_SERVER['HTTP_X_REAL_IP'];
211 }
212
213 if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
214 $xip = trim(current(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])));
215
216 if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
217 $ip_x_forwarded_for_before = $xip;
218 }
219 }
220
221 if( isset( $_SERVER['HTTP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
222 $ip_http_client_before = $_SERVER['HTTP_CLIENT_IP'];
223 }
224
225 if( isset( $_SERVER['HTTP_FORWARDED'] ) && filter_var( $_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP ) ) {
226 $ip_http_forwarded_before = $_SERVER['HTTP_FORWARDED'];
227 }
228
229 if( isset( $_SERVER['HTTP_X_FORWARDED'] ) && filter_var( $_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP ) ) {
230 $ip_x_forwarded_before = $_SERVER['HTTP_X_FORWARDED'];
231 }
232
233 $ip_remote_addr_before = $_SERVER['REMOTE_ADDR'];
234 $flp_checksum_before = ( isset( $_COOKIE['flp_checksum'] ) ) ? $_COOKIE['flp_checksum'] : '';
235 $flp_device_before = ( isset( $_COOKIE['flp_device'] ) ) ? $_COOKIE['flp_device'] : '';
236
237 $flpIP = [
238 'ip_x_sucuri_before' => $ip_x_sucuri_before,
239 'ip_incap_before' => $ip_incap_before,
240 'ip_http_cf_connecting_before' => $ip_http_cf_connecting_before,
241 'ip_x_real_before' => $ip_x_real_before,
242 'ip_x_forwarded_for_before' => $ip_x_forwarded_for_before,
243 'ip_http_client_before' => $ip_http_client_before,
244 'ip_http_forwarded_before' => $ip_http_forwarded_before,
245 'ip_x_forwarded_before' => $ip_x_forwarded_before,
246 'ip_remote_addr_before' => $ip_remote_addr_before,
247 'flp_checksum_before' => $flp_checksum_before,
248 'flp_device_before' => $flp_device_before,
249 ];
250
251 add_post_meta( $order_id, '_fraudlabspro_ip_before', $flpIP );
252 $table_name = $this->create_flpwc_table();
253 $this->add_flpwc_data($table_name, $order_id, '_fraudlabspro_ip_before', $flpIP);
254
255 if ( $this->validation_sequence != 'before' ) {
256 return;
257 }
258
259 $this->write_debug_log( 'Checkout order processed for Order ' . $order_id . '.');
260 $this->order = wc_get_order( $order_id );
261
262 if ( $this->validate_order() === false ) {
263 wc_add_notice( ( !empty( $this->fraud_message ) ) ? $this->fraud_message : 'This order ' . $this->order->get_id() . ' failed our fraud validation. Please contact us for more details.', 'error' );
264
265 global $woocommerce;
266 $woocommerce->cart->empty_cart();
267
268 if ( is_ajax() ) {
269 wp_send_json( array(
270 'result' => 'success',
271 'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', wc_get_cart_url(), $this->order ),
272 ) );
273 } else {
274 wp_safe_redirect(
275 apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', wc_get_cart_url(), $this->order )
276 );
277 exit;
278 }
279 }
280 }
281
282
283 /**
284 * Validate the order after payment gateway.
285 */
286 public function order_status_changed( $order_id, $old_status, $new_status ) {
287 if ( $this->validation_sequence == 'before' ) {
288 $order = wc_get_order( $order_id );
289 $result = get_post_meta( $order_id, '_fraudlabspro' );
290
291 if (!$result) {
292 $table_name = $this->create_flpwc_table();
293 $result = $this->get_flpwc_data($table_name, $order_id, '_fraudlabspro');
294 }
295
296 if (count($result) > 0) {
297 $idx = count( $result ) - 1;
298 if ( isset( $result[$idx] ) ) {
299 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
300 $row = json_decode( $result[$idx] );
301 }
302 } else {
303 $row = $result[$idx];
304 }
305 }
306
307 if (isset($row)) {
308 if ( is_array( $result[$idx] ) ) {
309 if ( $row['fraudlabspro_status'] == 'APPROVE' && $new_status == 'on-hold' ) {
310 $order->update_status( $this->approve_status, __( '', $this->namespace ) );
311 wp_safe_redirect($_SERVER['REQUEST_URI']);
312 exit;
313 }
314 } else {
315 if (isset($row->fraudlabspro_status)) {
316 if ( $row->fraudlabspro_status == 'APPROVE' && $new_status == 'on-hold' ) {
317 $order->update_status( $this->approve_status, __( '', $this->namespace ) );
318 wp_safe_redirect($_SERVER['REQUEST_URI']);
319 exit;
320 }
321 }
322 }
323 }
324 }
325
326 if ( $this->validation_sequence != 'after' ) {
327 return;
328 }
329
330 $this->order = wc_get_order( $order_id );
331
332 if ( in_array( $new_status, array( 'processing', 'on-hold', 'failed' ) ) ) {
333 $this->write_debug_log( 'Order status changed from ' . $old_status . ' to ' . $new_status . ' for Order ' . $order_id . '.');
334 $this->validate_order($old_status, $new_status);
335 }
336 }
337
338
339 /**
340 * Perform order validation.
341 */
342 public function validate_order($oldStatus = '', $newStatus = '') {
343 if ( $this->enabled != 'yes' ) {
344 $this->write_debug_log( 'FraudLabs Pro Validation not enabled. Order validation will not be performed.' );
345 return;
346 }
347
348 // Skip check order screened if Validate Order is Before submit order to payment gateway and enabled Advanced Velocity Screening
349 if ( ( $this->validation_sequence == 'before' ) && ( get_option('wc_settings_woocommerce-fraudlabs-pro_flp_advanced_velocity') == 'yes' ) ) {
350 $this->write_debug_log( 'Advanced Velocity Screening enabled.' );
351 } elseif ( ( $oldStatus == 'failed' ) && ( $newStatus == 'processing' ) ) {
352 $this->write_debug_log( 'Advanced Screening for Processing Order from Failed Order.' );
353 } elseif ( ( $oldStatus == 'failed' ) && ( $newStatus == 'on-hold' ) ) {
354 $this->write_debug_log( 'Advanced Screening for On Hold Order from Failed Order.' );
355 } else {
356 // Check if order has been screened
357 $result = get_post_meta( $this->order->get_id(), '_fraudlabspro' );
358
359 if (!$result) {
360 $table_name = $this->create_flpwc_table();
361 $result = $this->get_flpwc_data($table_name, $this->order->get_id(), '_fraudlabspro');
362 }
363
364 if( count( $result ) > 0 ) {
365 return;
366 }
367
368 // Double check if order has been screened
369 if ( $this->get_order_notes( $this->order->get_id() ) ) {
370 $result_order_note = $this->get_order_notes( $this->order->get_id() );
371 $this->write_debug_log( 'Order has been validated. Skip for FraudLabs Pro validation.' );
372 $this->write_debug_log( $result_order_note );
373 return;
374 }
375 }
376
377 // Prevent digital downloads before order is completed.
378 update_option( 'woocommerce_downloads_grant_access_after_payment', 'no' );
379
380 // $this->order->add_order_note( __( 'FraudLabs Pro validation has started.', $this->namespace ) );
381 $this->write_debug_log( 'FraudLabs Pro validation has started for Order ' . $this->order->get_id() . '.' );
382
383 $payment_gateway = wc_get_payment_gateway_by_order( $this->order );
384 $qty = 0;
385
386 $item_sku = '';
387 foreach ($this->order->get_items() as $item_id => $item_data) {
388 $item_quantity = $item_data->get_quantity();
389 $product = wc_get_product($item_data->get_product_id());
390 if ($product->get_sku() != '') {
391 $item_type = ($product->get_virtual()) ? 'virtual' : (($product->get_downloadable()) ? 'downloadable' :'physical');
392 $item_sku .= $product->get_sku() . ':' . $item_quantity . ':' . $item_type . ',';
393 }
394 $qty += $item_data['qty'];
395 }
396 $item_sku = rtrim($item_sku, ',');
397
398 if (preg_match('/^\d+(\.\d)*$/', $qty)) {
399 $qty = ceil($qty);
400 }
401
402 if ( isset( $payment_gateway->id ) ) {
403 switch ( $payment_gateway->id ) {
404 case 'stripe':
405 $payment_mode = 'creditcard';
406 break;
407
408 case 'bacs':
409 $payment_mode = 'bankdeposit';
410 break;
411
412 case 'cod':
413 $payment_mode = 'cod';
414 break;
415
416 case 'paypal':
417 case 'ppec_paypal':
418 case 'paypal_express':
419 $payment_mode = 'paypal';
420 break;
421
422 case 'elviauthorized':
423 $payment_mode = 'elviauthorized';
424 break;
425
426 case 'paymitco_gateway':
427 case 'universal_gateway':
428 $payment_mode = 'paymitco';
429 break;
430
431 case 'cybersource_sa_sop_credit_card':
432 case 'cybersource_credit_card':
433 $payment_mode = 'cybersource';
434 break;
435
436 case 'amazon_payments_advanced':
437 $payment_mode = 'amazonpay';
438 break;
439
440 case 'bitpay_checkout_gateway':
441 $payment_mode = 'bitcoin';
442 break;
443
444 default:
445 $payment_mode = $payment_gateway->id;
446 }
447 } else {
448 $payment_mode = 'others';
449 }
450
451 // Collect IP information after the payment gateway
452 $ip_x_sucuri_after = $ip_incap_after = $ip_http_cf_connecting_after = $ip_x_real_after = $ip_x_forwarded_for_after = $ip_http_client_after = $ip_http_forwarded_after = $ip_x_forwarded_after = '::1';
453
454 if ( isset( $_SERVER['HTTP_X_SUCURI_CLIENTIP'] ) && filter_var( $_SERVER['HTTP_X_SUCURI_CLIENTIP'], FILTER_VALIDATE_IP ) ) {
455 $ip_x_sucuri_after = $_SERVER['HTTP_X_SUCURI_CLIENTIP'];
456 }
457
458 if( isset( $_SERVER['HTTP_INCAP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_INCAP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
459 $ip_incap_after = $_SERVER['HTTP_INCAP_CLIENT_IP'];
460 }
461
462 if( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) && filter_var( $_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP ) ) {
463 $ip_http_cf_connecting_after = $_SERVER['HTTP_CF_CONNECTING_IP'];
464 }
465
466 if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
467 $ip_x_real_after = $_SERVER['HTTP_X_REAL_IP'];
468 }
469
470 if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
471 $xip = trim( current( explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) );
472
473 if ( filter_var( $xip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
474 $ip_x_forwarded_for_after = $xip;
475 }
476 }
477
478 if( isset( $_SERVER['HTTP_CLIENT_IP'] ) && filter_var( $_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP ) ) {
479 $ip_http_client_after = $_SERVER['HTTP_CLIENT_IP'];
480 }
481
482 if( isset( $_SERVER['HTTP_FORWARDED'] ) && filter_var( $_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP ) ) {
483 $ip_http_forwarded_after = $_SERVER['HTTP_FORWARDED'];
484 }
485
486 if( isset( $_SERVER['HTTP_X_FORWARDED'] ) && filter_var( $_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP ) ) {
487 $ip_x_forwarded_after = $_SERVER['HTTP_X_FORWARDED'];
488 }
489
490 // The internal function will check for X_REAL_IP followed by X_FORWARDED_FOR and REMOTE_ADDR
491 // Paypal incorrect IP address was solved using the below function
492 $client_ip = $this->order->get_customer_ip_address();
493
494 // Get IP result
495 $result_ip = get_post_meta( $this->order->get_id(), '_fraudlabspro_ip_before' );
496
497 if (!$result_ip) {
498 $table_name = $this->create_flpwc_table();
499 $result_ip = $this->get_flpwc_data($table_name, $this->order->get_id(), '_fraudlabspro_ip_before');
500 }
501
502 if( count( $result_ip ) > 0 ) {
503 if ( !is_array( $result_ip[0] ) && strpos( $result_ip[0], '\\' ) ) {
504 $result_ip[0] = str_replace( '\\', '', $result_ip[0] );
505 }
506
507 if ( !is_array( $result_ip[0] ) ) {
508 $row = json_decode( $result_ip[0] );
509
510 $ip_x_sucuri_before = $row->ip_x_sucuri_before;
511 $ip_incap_before = $row->ip_incap_before;
512 $ip_http_cf_connecting_before = $row->ip_http_cf_connecting_before;
513 $ip_x_real_before = $row->ip_x_real_before;
514 $ip_x_forwarded_for_before = $row->ip_x_forwarded_for_before;
515 $ip_http_client_before = $row->ip_http_client_before;
516 $ip_http_forwarded_before = $row->ip_http_forwarded_before;
517 $ip_x_forwarded_before = $row->ip_x_forwarded_before;
518 $ip_remote_addr_before = $row->ip_remote_addr_before;
519 $flp_checksum_before = $row->flp_checksum_before;
520 $flp_device_before = $row->flp_device_before;
521 } else {
522 $row = $result_ip[0];
523
524 $ip_x_sucuri_before = $row['ip_x_sucuri_before'];
525 $ip_incap_before = $row['ip_incap_before'];
526 $ip_http_cf_connecting_before = $row['ip_http_cf_connecting_before'];
527 $ip_x_real_before = $row['ip_x_real_before'];
528 $ip_x_forwarded_for_before = $row['ip_x_forwarded_for_before'];
529 $ip_http_client_before = $row['ip_http_client_before'];
530 $ip_http_forwarded_before = $row['ip_http_forwarded_before'];
531 $ip_x_forwarded_before = $row['ip_x_forwarded_before'];
532 $ip_remote_addr_before = $row['ip_remote_addr_before'];
533 $flp_checksum_before = $row['flp_checksum_before'];
534 $flp_device_before = $row['flp_device_before'];
535 }
536
537 if ( isset( $_SERVER['HTTP_X_SUCURI_CLIENTIP'] ) && $ip_x_sucuri_before != '::1' ) {
538 $client_ip = $ip_x_sucuri_before;
539 } elseif( isset( $_SERVER['HTTP_INCAP_CLIENT_IP'] ) && $ip_incap_before != '::1' ) {
540 $client_ip = $ip_incap_before;
541 } elseif( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) && $ip_http_cf_connecting_before != '::1' ){
542 $client_ip = $ip_http_cf_connecting_before;
543 } elseif ( isset( $_SERVER['HTTP_X_REAL_IP'] ) && $ip_x_real_before != '::1' ) {
544 $client_ip = $ip_x_real_before;
545 } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) && $ip_x_forwarded_for_before != '::1' ) {
546 $client_ip = $ip_x_forwarded_for_before;
547 } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
548 $client_ip = $ip_remote_addr_before;
549 if (filter_var($ip_remote_addr_before, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
550 if (!filter_var($ip_remote_addr_before, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
551 $client_ip = '127.0.0.1';
552 }
553 }
554 }
555
556 if (!empty($real_ip_detect) && ($real_ip_detect != 'no_override')) {
557 switch ($real_ip_detect) {
558 case 'remote_addr':
559 if (isset($_SERVER['REMOTE_ADDR']) && ($ip_remote_addr_before != '::1')) {
560 $client_ip = $ip_remote_addr_before;
561 }
562 break;
563
564 case 'http_cf_connecting_ip':
565 if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && ($ip_http_cf_connecting_before != '::1')) {
566 $client_ip = $ip_http_cf_connecting_before;
567 }
568 break;
569
570 case 'http_client_ip':
571 if (isset($_SERVER['HTTP_CLIENT_IP']) && ($ip_http_client_before != '::1')) {
572 $client_ip = $ip_http_client_before;
573 }
574 break;
575
576 case 'http_forwarded':
577 if (isset($_SERVER['HTTP_FORWARDED']) && ($ip_http_forwarded_before != '::1')) {
578 $client_ip = $ip_http_forwarded_before;
579 }
580 break;
581
582 case 'http_incap_client_ip':
583 if (isset($_SERVER['HTTP_INCAP_CLIENT_IP']) && ($ip_incap_before != '::1')) {
584 $client_ip = $ip_incap_before;
585 }
586 break;
587
588 case 'http_x_forwarded':
589 if (isset($_SERVER['HTTP_X_FORWARDED']) && ($ip_x_forwarded_before != '::1')) {
590 $client_ip = $ip_x_forwarded_before;
591 }
592 break;
593
594 case 'http_x_forwarded_for':
595 if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && ($ip_x_forwarded_for_before != '::1')) {
596 $client_ip = $ip_x_forwarded_for_before;
597 }
598 break;
599
600 case 'http_x_real_ip':
601 if (isset($_SERVER['HTTP_X_REAL_IP']) && ($ip_x_real_before != '::1')) {
602 $client_ip = $ip_x_real_before;
603 }
604 break;
605
606 case 'http_x_sucuri_clientip':
607 if (isset($_SERVER['HTTP_X_SUCURI_CLIENTIP']) && ($ip_x_sucuri_before != '::1')) {
608 $client_ip = $ip_x_sucuri_before;
609 }
610 break;
611 }
612 }
613 } elseif ( $ip_x_real_after != '::1' ) {
614 // Get IP via order from eBay [YLL-612-89047]
615 $client_ip = $ip_x_real_after;
616 }
617
618 if ( !isset( $ip_x_sucuri_before ) ) { $ip_x_sucuri_before = '::1'; }
619 if ( !isset( $ip_incap_before ) ) { $ip_incap_before = '::1'; }
620 if ( !isset( $ip_http_cf_connecting_before ) ) { $ip_http_cf_connecting_before = '::1'; }
621 if ( !isset( $ip_x_real_before ) ) { $ip_x_real_before = '::1'; }
622 if ( !isset( $ip_x_forwarded_for_before ) ) { $ip_x_forwarded_for_before = '::1'; }
623 if ( !isset( $ip_http_client_before ) ) { $ip_http_client_before = '::1'; }
624 if ( !isset( $ip_http_forwarded_before ) ) { $ip_http_forwarded_before = '::1'; }
625 if ( !isset( $ip_x_forwarded_before ) ) { $ip_x_forwarded_before = '::1'; }
626 if ( !isset( $ip_remote_addr_before ) ) { $ip_remote_addr_before = '::1'; }
627 if ( !isset( $flp_checksum_before ) ) { $flp_checksum_before = ''; }
628 if ( !isset( $flp_device_before ) ) { $flp_device_before = ''; }
629
630 $credit_card_number = '';
631 $cc_key = '';
632 $postData = '';
633 if ( !empty( $_POST ) ) {
634 // Get BIN number data
635 foreach ( $_POST as $key => $value ) {
636 if (is_string($value)) {
637 $value = preg_replace ('/\D/', '', $value);
638 if ( $this->is_credit_card( $value ) ) {
639 if ( strpos( $key, 'wc_order_attribution' ) !== false ) {}
640 elseif ( strpos( $key, 'billing_' ) !== false ) {}
641 elseif ( strpos( $key, 'shipping_' ) !== false ) {}
642 elseif ( strpos( $key, 'phone' ) !== false ) {}
643 else {
644 $credit_card_number = $value;
645 $cc_key = $key;
646 break;
647 }
648 }
649 }
650 }
651 // Collect data to review
652 foreach ( $_POST as $key => $value ) {
653 if (is_string($value)) {
654 $value = preg_replace ('/\D/', '', $value);
655 if (strlen($value) > 10) {
656 $postData .= $key . ':' . $value . ',';
657 }
658 }
659 }
660 $postData = rtrim($postData, ',');
661 }
662
663 $binNo = '';
664 $binNo = get_post_meta( $this->order->get_id(), '_flp_bin_no' );
665
666 if (empty($binNo)) {
667 $binNo = $this->order->get_meta( '_flp_bin_no', false );
668 }
669
670 if (empty($binNo)) {
671 $table_name = $this->create_flpwc_table();
672 $binNo = $this->get_flpwc_data($table_name, $this->order->get_id(), '_flp_bin_no');
673 }
674
675 $couponCode = '';
676 $couponAmt = '';
677 $couponType = '';
678 if ( $this->order->get_coupon_codes() != '' ) {
679 foreach( $this->order->get_coupon_codes() as $coupon_code ) {
680 $coupon = new WC_Coupon($coupon_code);
681 $couponCode = $coupon->get_code();
682 $couponAmt = $coupon->get_amount();
683 $couponType = $coupon->get_discount_type();
684 }
685 }
686
687 $current_user = wp_get_current_user();
688 if ( $current_user !== '' ) {
689 $current_username = $current_user->user_login;
690 } else {
691 $current_username = '';
692 }
693
694 $bill_country = $ship_country = '';
695 $bill_country = ( $this->order->get_billing_country() !== "default" ) ? $this->order->get_billing_country() : '';
696 $ship_country = ( $this->order->get_shipping_country() !== "default" ) ? $this->order->get_shipping_country() : '';
697
698 $flpCallbackNonce = $this->create_custom_nonce('check-flp-callback');
699
700 $queries = [
701 'key' => $this->api_key,
702 'format' => 'json',
703 'ip' => ( filter_var( $this->test_ip, FILTER_VALIDATE_IP ) ) ? $this->test_ip : $client_ip,
704 'ip_x_sucuri_before' => $ip_x_sucuri_before,
705 'ip_incap_before' => $ip_incap_before,
706 'ip_http_cf_connecting_before' => $ip_http_cf_connecting_before,
707 'ip_x_real_before' => $ip_x_real_before,
708 'ip_x_forwarded_for_before' => $ip_x_forwarded_for_before,
709 'ip_http_client_before' => $ip_http_client_before,
710 'ip_http_forwarded_before' => $ip_http_forwarded_before,
711 'ip_x_forwarded_before' => $ip_x_forwarded_before,
712 'ip_remote_addr_before' => $ip_remote_addr_before,
713 'ip_x_sucuri_after' => $ip_x_sucuri_after,
714 'ip_incap_after' => $ip_incap_after,
715 'ip_http_cf_connecting_after' => $ip_http_cf_connecting_after,
716 'ip_x_real_after' => $ip_x_real_after,
717 'ip_x_forwarded_for_after' => $ip_x_forwarded_for_after,
718 'ip_http_client_after' => $ip_http_client_after,
719 'ip_http_forwarded_after' => $ip_http_forwarded_after,
720 'ip_x_forwarded_after' => $ip_x_forwarded_after,
721 'first_name' => $this->order->get_billing_first_name(),
722 'last_name' => $this->order->get_billing_last_name(),
723 'bill_to' => $this->order->get_billing_company(),
724 'bill_addr' => trim( $this->order->get_billing_address_1() . ' ' . $this->order->get_billing_address_2() ),
725 'bill_city' => $this->order->get_billing_city(),
726 'bill_state' => $this->order->get_billing_state(),
727 'bill_zip_code' => $this->order->get_billing_postcode(),
728 'bill_country' => $bill_country,
729 'user_phone' => $this->order->get_billing_phone(),
730 'ship_first_name' => $this->order->get_shipping_first_name(),
731 'ship_last_name' => $this->order->get_shipping_last_name(),
732 'ship_addr' => trim( $this->order->get_shipping_address_1() . ' ' . $this->order->get_shipping_address_2() ),
733 'ship_city' => $this->order->get_shipping_city(),
734 'ship_state' => $this->order->get_shipping_state(),
735 'ship_zip_code' => $this->order->get_shipping_postcode(),
736 'ship_country' => $ship_country,
737 'email' => $this->order->get_billing_email(),
738 'email_domain' => substr( $this->order->get_billing_email(), strpos( $this->order->get_billing_email(), '@' ) + 1 ),
739 'email_hash' => $this->hash_string( $this->order->get_billing_email() ),
740 'user_order_id' => $this->order->get_order_number(),
741 'amount' => $this->order->get_total(),
742 'quantity' => $qty,
743 'currency' => $this->order->get_currency(),
744 'payment_gateway' => ( $payment_gateway->id ) ?? 'others',
745 'payment_mode' => $payment_mode,
746 'wc_payment_method' => ( $payment_gateway->id ) ??'others',
747 'flp_checksum' => ( $_COOKIE['flp_checksum'] ) ?? $flp_checksum_before,
748 'device_fingerprint' => ( $_COOKIE['flp_device'] ) ?? $flp_device_before,
749 'bin_no' => (( $credit_card_number ) ? substr( $credit_card_number, 0, 6 ) : (( $binNo ) ? substr( $binNo[0], 0, 6 ) : '')),
750 'card_hash' => ( $credit_card_number ) ? $this->hash_string( $credit_card_number ) : '',
751 'validation_sequence' => $this->validation_sequence,
752 'advanced_velocity_screening' => ( get_option('wc_settings_woocommerce-fraudlabs-pro_flp_advanced_velocity') == "yes" ) ? 'enabled' : 'disabled',
753 'source' => 'woocommerce',
754 'source_version' => '2.24.2',
755 'items' => $item_sku,
756 'cc_key' => $cc_key,
757 'username' => $current_username,
758 'avs_result' => ( $_SESSION['flp_avs'] ) ?? '',
759 'cvv_result' => ( $_SESSION['flp_cvv'] ) ?? '',
760 'coupon_code' => $couponCode,
761 'coupon_amount' => $couponAmt,
762 'coupon_type' => $couponType,
763 'wc_post_data' => $postData,
764 'is_wc_failed_order' => ($newStatus == 'failed') ? true : false,
765 'reject_wc_failed_order' => (get_option('wc_settings_woocommerce-fraudlabs-pro_reject_failed_order') == 'yes') ? true : false,
766 'callback_nonce' => $flpCallbackNonce,
767 ];
768
769 if ( isset( $_SESSION['flp_avs'] ) ) {
770 unset ($_SESSION['flp_avs']);
771 }
772 if ( isset( $_SESSION['flp_cvv'] ) ) {
773 unset ($_SESSION['flp_cvv']);
774 }
775
776 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/screen', $queries );
777
778 // Give up fraud check if having network issue
779 if ( ( $response = json_decode( $request ) ) === null ) {
780 $this->write_debug_log( 'FraudLabs Pro validation has been skipped for order ' . $this->order->get_id() . '.' );
781 $this->write_debug_log( 'Error for order ' . $this->order->get_id() . ': ' . $request );
782 $this->order->add_order_note( __( 'FraudLabs Pro validation has been skipped. ' . $request, $this->namespace ) );
783
784 // Save the static data to prevent duplicate checking
785 $staticData = [
786 'order_id' => $this->order->get_id(),
787 'ip_address' => ( filter_var( $this->test_ip, FILTER_VALIDATE_IP ) ) ? $this->test_ip : $client_ip,
788 'fraudlabspro_id' => '',
789 'api_key' => $this->api_key,
790 ];
791
792 $add_post_meta_result = add_post_meta( $this->order->get_id(), '_fraudlabspro', $staticData );
793 if ( ! $add_post_meta_result ) {
794 $this->write_debug_log( 'ERROR 101 - add_post_meta function failed.' );
795 }
796
797 $table_name = $this->create_flpwc_table();
798 $add_post_meta_result_hpos = $this->add_flpwc_data($table_name, $this->order->get_id(), '_fraudlabspro', $staticData);
799 if ( ! $add_post_meta_result_hpos ) {
800 $this->write_debug_log( 'ERROR 101 - add_post_meta HPOS failed.' );
801 }
802
803 return;
804 }
805
806 // Make sure response is an object
807 if ( ! is_object( $response ) ) {
808 $this->write_debug_log( 'FraudLabs Pro validation has been skipped for order ' . $this->order->get_id() . ' due to network issue.' );
809 $this->order->add_order_note( __( 'FraudLabs Pro validation has been skipped due to network issues.', $this->namespace ) );
810
811 // Save the static data to prevent duplicate checking
812 $staticData = [
813 'order_id' => $this->order->get_id(),
814 'ip_address' => ( filter_var( $this->test_ip, FILTER_VALIDATE_IP ) ) ? $this->test_ip : $client_ip,
815 'fraudlabspro_id' => '',
816 'api_key' => $this->api_key,
817 ];
818
819 $add_post_meta_result = add_post_meta( $this->order->get_id(), '_fraudlabspro', $staticData );
820 if ( ! $add_post_meta_result ) {
821 $this->write_debug_log( 'ERROR 102 - add_post_meta function failed.' );
822 }
823
824 $table_name = $this->create_flpwc_table();
825 $add_post_meta_result_hpos = $this->add_flpwc_data($table_name, $this->order->get_id(), '_fraudlabspro', $staticData);
826 if ( ! $add_post_meta_result_hpos ) {
827 $this->write_debug_log( 'ERROR 102 - add_post_meta HPOS failed.' );
828 }
829
830 return;
831 }
832
833 // Save fraud check result
834 $flpResult = [
835 'order_id' => $this->order->get_id(),
836 'is_country_match' => ($response->billing_address->is_ip_country_match) ? 'Y' : 'N',
837 'is_high_risk_country' => '',
838 'distance_in_km' => $response->billing_address->ip_distance_in_km,
839 'distance_in_mile' => $response->billing_address->ip_distance_in_mile,
840 'ip_address' => ( filter_var( $this->test_ip, FILTER_VALIDATE_IP ) ) ? $this->test_ip : $client_ip,
841 'ip_country' => $response->ip_geolocation->country_code,
842 'ip_region' => $response->ip_geolocation->region,
843 'ip_city' => $response->ip_geolocation->city,
844 'ip_continent' => $response->ip_geolocation->continent,
845 'ip_latitude' => $response->ip_geolocation->latitude,
846 'ip_longitude' => $response->ip_geolocation->longitude,
847 'ip_timezone' => $response->ip_geolocation->timezone,
848 'ip_elevation' => $response->ip_geolocation->elevation,
849 'ip_domain' => $response->ip_geolocation->domain,
850 'ip_mobile_mnc' => $response->ip_geolocation->mobile_mnc,
851 'ip_mobile_mcc' => $response->ip_geolocation->mobile_mcc,
852 'ip_mobile_brand' => $response->ip_geolocation->mobile_brand,
853 'ip_netspeed' => $response->ip_geolocation->netspeed,
854 'ip_isp_name' => $response->ip_geolocation->isp_name,
855 'ip_usage_type' => is_array($response->ip_geolocation->usage_type) ? implode(', ', $response->ip_geolocation->usage_type) : $response->ip_geolocation->usage_type,
856 'is_free_email' => ($response->email_address->is_free) ? 'Y' : 'N',
857 'is_new_domain_name' => ($response->email_address->is_new_domain_name) ? 'Y' : 'N',
858 'is_proxy_ip_address' => ($response->ip_geolocation->is_proxy) ? 'Y' : 'N',
859 'is_bin_found' => ($response->credit_card->is_bin_exist) ? 'Y' : 'N',
860 'is_bin_country_match' => ($response->credit_card->is_bin_country_match) ? 'Y' : 'N',
861 'is_bin_name_match' => '',
862 'is_bin_phone_match' => '',
863 'is_bin_prepaid' => ($response->credit_card->is_prepaid) ? 'Y' : 'N',
864 'card_issuing_country' => ($response->credit_card->card_issuing_country) ?? '',
865 'is_address_ship_forward' => ($response->shipping_address->is_address_ship_forward) ? 'Y' : 'N',
866 'is_bill_ship_city_match' => ($response->shipping_address->is_bill_city_match) ? 'Y' : 'N',
867 'is_bill_ship_state_match' => ($response->shipping_address->is_bill_state_match) ? 'Y' : 'N',
868 'is_bill_ship_country_match' => ($response->shipping_address->is_bill_country_match) ? 'Y' : 'N',
869 'is_bill_ship_postal_match' => ($response->shipping_address->is_bill_postcode_match) ? 'Y' : 'N',
870 'is_ip_blacklist' => ($response->ip_geolocation->is_in_blacklist) ? 'Y' : 'N',
871 'is_email_blacklist' => ($response->email_address->is_in_blacklist) ? 'Y' : 'N',
872 'is_credit_card_blacklist' => ($response->credit_card->is_in_blacklist) ? 'Y' : 'N',
873 'is_device_blacklist' => ($response->device->is_in_blacklist) ? 'Y' : 'N',
874 'is_user_blacklist' => ($response->username->is_in_blacklist) ? 'Y' : 'N',
875 'is_email_disposable' => is_null($response->email_address->is_disposable) ? '-' : ($response->email_address->is_disposable ? 'Y' : 'N'),
876 'is_phone_disposable' => is_null($response->phone_number->is_disposable) ? '-' : ($response->phone_number->is_disposable ? 'Y' : 'N'),
877 'is_phone_verified' => 'No',
878 'fraudlabspro_score' => $response->fraudlabspro_score,
879 'fraudlabspro_distribution' => '',
880 'fraudlabspro_status' => $response->fraudlabspro_status,
881 'fraudlabspro_id' => $response->fraudlabspro_id,
882 'fraudlabspro_error_code' => ($response->error->error_code) ?? '',
883 'fraudlabspro_message' => ($response->error->error_message) ?? '',
884 'fraudlabspro_credits' => $response->remaining_credits,
885 'fraudlabspro_rules' => is_array($response->fraudlabspro_rules) ? implode(', ', $response->fraudlabspro_rules) : $response->fraudlabspro_rules,
886 'flp_callback_nonce' => $flpCallbackNonce,
887 'api_key' => $this->api_key,
888 ];
889
890 $add_post_meta_result = add_post_meta( $this->order->get_id(), '_fraudlabspro', $flpResult );
891 if ( ! $add_post_meta_result ) {
892 $this->write_debug_log( 'ERROR 103 - add_post_meta function failed.' );
893 }
894
895 $table_name = $this->create_flpwc_table();
896 $add_post_meta_result_hpos = $this->add_flpwc_data($table_name, $this->order->get_id(), '_fraudlabspro', $flpResult);
897 if ( ! $add_post_meta_result_hpos ) {
898 $this->write_debug_log( 'ERROR 103 - add_post_meta HPOS failed.' );
899 }
900
901 $flpErrorMsg = ($response->error->error_message) ?? '';
902 if ( strpos( $flpErrorMsg, 'SYSTEM DATABASE ERROR' ) !== false ) {
903 $this->order->add_order_note( __( 'An error has occurred in the FraudLabs Pro system database.', $this->namespace ) );
904 }
905
906 $this->order->add_order_note( __( 'FraudLabs Pro Status: ' . $response->fraudlabspro_status . '. Transaction ID: ' . $response->fraudlabspro_id, $this->namespace ) );
907 $this->write_debug_log( 'FraudLabs Pro validation has been completed for Order ' . $this->order->get_id() . '. Status: ' . $response->fraudlabspro_status . ', Transaction ID: ' . $response->fraudlabspro_id );
908
909 if ( strpos( $flpErrorMsg, 'SYSTEM DATABASE ERROR' ) !== false ) {
910 if ( $this->db_err_status && $this->db_err_status != $this->order->get_status() ) {
911 $this->order->update_status( $this->db_err_status, __( '', $this->namespace ) );
912 }
913 }
914 elseif ( ($response->fraudlabspro_status == 'REJECT') && ($newStatus != 'failed') ) {
915 if ( $this->reject_status && $this->reject_status != $this->order->get_status() ) {
916 $this->order->update_status( $this->reject_status, __( '', $this->namespace ) );
917 }
918 }
919 elseif ( ($response->fraudlabspro_status == 'REVIEW') && ($newStatus != 'failed') ) {
920 if ( $this->review_status && ($this->review_status != $this->order->get_status()) ) {
921 $this->order->update_status( $this->review_status, __( '', $this->namespace ) );
922 }
923 }
924 elseif ( ($response->fraudlabspro_status == 'APPROVE') && ($newStatus != 'failed') ) {
925 if ( $this->approve_status && $this->approve_status != $this->order->get_status() && $this->order->get_status() != 'wc-completed' ) {
926 $this->order->update_status( $this->approve_status, __( '', $this->namespace ) );
927 }
928 }
929
930 if ( ( $this->notification_approve == 'yes' && $response->fraudlabspro_status == 'APPROVE' ) || ( $this->notification_review == 'yes' && $response->fraudlabspro_status == 'REVIEW' ) || ( $this->notification_reject == 'yes' && $response->fraudlabspro_status == 'REJECT' ) ) {
931 $first_name = $this->order->get_billing_first_name();
932 $last_name = $this->order->get_billing_last_name();
933
934 // Use zaptrigger API to get zap information
935 $request = wp_remote_get( 'https://api.fraudlabspro.com/v2/zaptrigger?' . http_build_query( array(
936 'key' => $this->api_key,
937 'format' => 'json'
938 ) ) );
939
940 if ( ! is_wp_error( $request ) ) {
941 // Get the HTTP response
942 $zap_trigger = json_decode( wp_remote_retrieve_body( $request ) );
943
944 if ( is_object( $zap_trigger ) ) {
945 if (isset($zap_trigger->target_url)) {
946 $target_url = $zap_trigger->target_url;
947 }
948 }
949 }
950
951 if ( ! empty( $target_url ) ) {
952 $zapresponse = $this->http($target_url, [
953 'id' => $response->fraudlabspro_id,
954 'date_created' => gmdate('Y-m-d H:i:s'),
955 'flp_status' => $response->fraudlabspro_status,
956 'full_name' => $first_name . ' ' . $last_name,
957 'email' => $this->order->get_billing_email(),
958 'order_id' => $this->order->get_id(),
959 ]);
960 $zapdata = json_decode($zapresponse);
961 if ( is_object( $zapdata ) ) {
962 if ( $zapdata->status == 'success' ) {
963 $this->write_debug_log( 'Hooks sent successful.' );
964 } else {
965 $this->write_debug_log( 'Hooks sent failed.' );
966 }
967 } else {
968 $this->write_debug_log( 'Failed in sending hook to Zapier.' );
969 }
970 } else {
971 $this->write_debug_log( 'Zapier target_url not found.' );
972 }
973 }
974
975 if ( $response->fraudlabspro_status == 'REJECT' ) {
976 return false;
977 }
978
979 return true;
980 }
981
982
983 /**
984 * Includes required scripts and styles.
985 */
986 public function admin_enqueue_scripts( $hook ) {
987 if (current_user_can('administrator')) {
988 wp_enqueue_script( 'fraudlabspro_woocommerce_admin_script', plugins_url( '/assets/js/script.js', WC_FLP_DIR ), array( 'jquery' ), '1.0', true );
989 }
990
991 wp_enqueue_style( 'fraudlabs_pro_admin_menu_styles', untrailingslashit( plugins_url( '/', WC_FLP_DIR ) ) . '/assets/css/style.css', array() );
992
993 if ( $hook == 'plugins.php' ) {
994 // Add in required libraries for feedback modal
995 wp_enqueue_script('jquery-ui-dialog');
996 wp_enqueue_style('wp-jquery-ui-dialog');
997
998 wp_enqueue_script( 'fraudlabs_pro_woocommerce_admin_script', plugins_url( '/assets/js/feedback.js', WC_FLP_DIR ), array( 'jquery' ), true );
999 }
1000 elseif ( $hook != 'toplevel_page_woocommerce-fraudlabs-pro ' ) {
1001 return;
1002 }
1003 }
1004
1005
1006 /**
1007 * Add wizard form upon plugin activation in dashboard.
1008 */
1009 public function admin_notices() {
1010 $current_screen = get_current_screen();
1011
1012 if ( 'plugins' == $current_screen->parent_base ) {
1013 $setup_fraudlabs_pro = false;
1014
1015 if ($this->api_key != '') {
1016 $setup_fraudlabs_pro = true;
1017 }
1018
1019 if (!$setup_fraudlabs_pro) {
1020 echo '
1021 <div id="modal-step-1" class="fraudlabs-pro-modal" style="display:block">
1022 <div class="fraudlabs-pro-modal-content">
1023 <script type="text/javascript" src="https://use.fontawesome.com/30858dc40a.js"></script>
1024 <button type="button" class="dismiss-button"><i class="fa fa-times-circle"></i></button>
1025 <div align="center">
1026 <h1>Set Up FraudLabs Pro API Key</h1>
1027 <table class="setup" width="200">
1028 <tr>
1029 <td align="center">
1030 <img src="' . plugins_url('/assets/images/step-1-selected.png', WC_FLP_DIR) . '" width="32" height="32" align="center"><br>
1031 <strong>Step 1</strong>
1032 </td>
1033 <td align="center">
1034 <img src="' . plugins_url('/assets/images/step-2.png', WC_FLP_DIR) . '" width="32" height="32" align="center"><br>
1035 Step 2
1036 </td>
1037 </tr>
1038 </table>
1039 <div class="line"></div>
1040 </div>
1041
1042 <form>
1043 <p class="description" style="padding-top: 6px;margin-bottom: 18px;">
1044 Protect your WooCommerce store from payment fraud by connecting your API key below.
1045 </p>
1046 <p>
1047 <label for="setup_flp_key"><strong>Enter FraudLabs Pro API Key</strong></label>
1048 <input type="text" id="setup_flp_key" class="regular-text code" maxlength="64" style="width:100%;margin-top:6px;padding:5px 10px;border: 1px solid #b9b9b9;">
1049 </p>
1050 <div class="help-box">
1051 <p class="description">✨ <strong>New to FraudLabs Pro?</strong></p>
1052 <p class="description" style="font-size:14px;margin-bottom:10px;">
1053 Create a free account and get your API key instantly — no credit card required.
1054 </p>
1055 <a href="https://www.fraudlabspro.com/subscribe?id=1#woocommerce-pltwzd" target="_blank" style="font-size:14px;margin-top:10px;"><strong>Get Free API Key »</strong></a>
1056 </div>
1057 </form>
1058 <p style="text-align:right;margin-top:15px;margin-bottom:0;">
1059 <button id="btn-to-step-2" class="button button-primary" disabled>Next &raquo;</button>
1060 </p>
1061
1062 </div>
1063 </div>
1064 <div id="modal-step-2" class="fraudlabs-pro-modal">
1065 <div class="fraudlabs-pro-modal-content">
1066 <div align="center">
1067 <h1>Validate FraudLabs Pro API Key</h1>
1068 <table class="setup" width="200">
1069 <tr>
1070 <td align="center">
1071 <img src="' . plugins_url('/assets/images/step-1.png', WC_FLP_DIR) . '" width="32" height="32" align="center"><br>
1072 Step 1
1073 </td>
1074 <td align="center">
1075 <img src="' . plugins_url('/assets/images/step-2-selected.png', WC_FLP_DIR) . '" width="32" height="32" align="center"><br>
1076 <strong>Step 2</strong>
1077 </td>
1078 </tr>
1079 </table>
1080 <div class="line"></div>
1081 </div>
1082
1083 <form style="height:140px;padding-top:6px;">
1084 <div id="fraudlabs_pro_key_validation_status"></div>
1085 </form>
1086 <p style="text-align:right;margin-top:30px">
1087 <button id="btn-to-step-1" class="button button-primary" disabled>&laquo; Previous</button>
1088 <button id="btn-to-step-3" class="button button-primary" disabled>Next &raquo;</button>
1089 </p>
1090 </div>
1091 </div>
1092 <div id="modal-step-3" class="fraudlabs-pro-modal">
1093 <div class="fraudlabs-pro-modal-content">
1094 <div>
1095 <div align="center">
1096 <img src="' . plugins_url('/assets/images/step-end.png', WC_FLP_DIR) . '" width="300" height="225" align="center">
1097 </div>
1098 <p style="margin-bottom: 20px;">
1099 <span class="dashicons dashicons-yes-alt" style="width:25px;height:25px;font-size:25px;color: #039953;"></span>
1100 Fraud protection is now enabled for your store.
1101 </p>
1102 <p style="margin-bottom:0;"><strong>What to do next?</strong></p>
1103 <ul style="margin-top:10px;font-size:15px;">
1104 <li>👉 <a href="' . admin_url('admin.php?page=woocommerce-fraudlabs-pro&tab=order') . '">Review and update order settings</a></li>
1105 <li>👉 <a href="https://www.fraudlabspro.com/merchant/rule" target="_blank">Customize your fraud validation rules</a></li>
1106 <li>👉 <a href="https://www.fraudlabspro.com/resources/categories/woocommerce" target="_blank">Explore tutorials and guides</a></li>
1107 </ul>
1108 </div>
1109
1110 <p style="text-align:right;margin-top:15px">
1111 <button class="button button-primary" onclick="window.location.href=\'' . admin_url('admin.php?page=woocommerce-fraudlabs-pro') . '\';">Done</button>
1112 </p>
1113 </div>
1114 </div>
1115 <input type="hidden" id="validate_api_key_nonce" value="' . wp_create_nonce('validate-api-key') . '">';
1116 }
1117 }
1118 }
1119
1120
1121 /**
1122 * Admin menu.
1123 */
1124 public function admin_menu() {
1125 add_menu_page( 'FraudLabs Pro', 'FraudLabs Pro', 'manage_options', 'woocommerce-fraudlabs-pro', array( $this, 'settings_page' ), 'dashicons-admin-fraudlabs-pro', 30 );
1126 }
1127
1128
1129 /**
1130 * Settings page.
1131 */
1132 public function settings_page() {
1133 if (!current_user_can('administrator')) {
1134 $this->write_debug_log( 'Not logged in as administrator. Settings page will not be shown.' );
1135 return;
1136 }
1137
1138 $form_status = '';
1139
1140 wp_enqueue_script( 'jquery' );
1141
1142 $tab = (isset($_GET['tab'])) ? sanitize_text_field($_GET['tab']) : 'settings';
1143 switch ($tab) {
1144 case 'order':
1145 $form_status = '';
1146
1147 $wc_order_statuses = wc_get_order_statuses();
1148 $wc_order_statuses[''] = 'No Status Change';
1149 $validation_sequence = ( isset( $_POST['validation_sequence'] ) ) ? sanitize_text_field($_POST['validation_sequence']) : $this->get_setting( 'validation_sequence' );
1150 $enable_wc_fraudlabspro_advanced_velocity = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro_advanced_velocity'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro_advanced_velocity'] ) ) ) ? 'no' : $this->get_setting( 'flp_advanced_velocity' ) );
1151 $approve_status = ( isset( $_POST['approve_status'] ) ) ? sanitize_text_field($_POST['approve_status']) : $this->get_setting( 'approve_status' );
1152 $review_status = ( isset( $_POST['review_status'] ) ) ? sanitize_text_field($_POST['review_status']) : $this->get_setting( 'review_status' );
1153 $reject_status = ( isset( $_POST['reject_status'] ) ) ? sanitize_text_field($_POST['reject_status']) : $this->get_setting( 'reject_status' );
1154 $db_err_status = ( isset( $_POST['db_err_status'] ) ) ? sanitize_text_field($_POST['db_err_status']) : $this->get_setting( 'db_err_status' );
1155 $enable_wc_fraudlabspro_auto_change_status = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro_auto_change_status'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro_auto_change_status'] ) ) ) ? 'no' : $this->get_setting( 'change_status_auto' ) );
1156 $enable_wc_fraudlabspro_reject_fail_status = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro_reject_fail_status'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro_reject_fail_status'] ) ) ) ? 'no' : $this->get_setting( 'reject_failed_order' ) );
1157 $fraud_message = ( isset( $_POST['fraud_message'] ) ) ? sanitize_text_field($_POST['fraud_message']) : $this->get_setting( 'fraud_message' );
1158 $real_ip_detect = ( isset( $_POST['real_ip_detect'] ) ) ? sanitize_text_field($_POST['real_ip_detect']) : $this->get_setting( 'real_ip_detect' );
1159 $test_ip = ( isset( $_POST['test_ip'] ) ) ? sanitize_text_field(esc_attr($_POST['test_ip'])) : $this->get_setting( 'test_ip' );
1160 $enable_wc_fraudlabspro_report_expand = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro_report_expand'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro_report_expand'] ) ) ) ? 'no' : $this->get_setting( 'expand_report' ) );
1161 $enable_wc_fraudlabspro_debug_log = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro_debug_log'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro_debug_log'] ) ) ) ? 'no' : $this->get_setting( 'debug_log' ) );
1162 $wc_fraudlabspro_debug_log_path = ( isset( $_POST['wc_fraudlabspro_debug_log_path'] ) ) ? sanitize_text_field(esc_url($_POST['wc_fraudlabspro_debug_log_path'])) : $this->get_setting( 'debug_log_path' );
1163
1164 if ( isset( $_POST['submit'] ) ) {
1165 check_admin_referer('save-settings', '_wpnonce_save_settings');
1166
1167 if ( !empty( $test_ip ) && !filter_var( $test_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
1168 $test_ip = '';
1169 $form_status .= '
1170 <div id="message" class="error">
1171 <p><strong>ERROR</strong>: Please enter a valid IP address.</p>
1172 </div>';
1173 }
1174
1175 if (!empty($wc_fraudlabspro_debug_log_path)) {
1176 if (!is_writable(ABSPATH . $wc_fraudlabspro_debug_log_path)) {
1177 $wc_fraudlabspro_debug_log_path = '';
1178 $form_status .= '
1179 <div id="message" class="error">
1180 <p><strong>ERROR</strong>: Please enter a valid Debug Log Path.</p>
1181 </div>';
1182 }
1183 }
1184
1185 if ( empty( $form_status ) ) {
1186 if ($validation_sequence == "before") {
1187 $approve_status = $review_status = $db_err_status = "";
1188 }
1189 $this->update_setting( 'validation_sequence', $validation_sequence );
1190 $this->update_setting( 'flp_advanced_velocity', $enable_wc_fraudlabspro_advanced_velocity );
1191 $this->update_setting( 'approve_status', $approve_status );
1192 $this->update_setting( 'review_status', $review_status );
1193 $this->update_setting( 'reject_status', $reject_status );
1194 $this->update_setting( 'db_err_status', $db_err_status );
1195 $this->update_setting( 'change_status_auto', $enable_wc_fraudlabspro_auto_change_status );
1196 $this->update_setting( 'reject_failed_order', $enable_wc_fraudlabspro_reject_fail_status );
1197 $this->update_setting( 'fraud_message', $fraud_message );
1198 $this->update_setting( 'real_ip_detect', $real_ip_detect );
1199 $this->update_setting( 'test_ip', $test_ip );
1200 $this->update_setting( 'expand_report', $enable_wc_fraudlabspro_report_expand );
1201 $this->update_setting( 'debug_log', $enable_wc_fraudlabspro_debug_log );
1202 $this->update_setting( 'debug_log_path', $wc_fraudlabspro_debug_log_path );
1203
1204 $form_status = '
1205 <div id="message" class="updated">
1206 <p>Changes saved.</p>
1207 </div>';
1208 }
1209 }
1210
1211 echo '
1212 <script>
1213 jQuery("#approve_status").change(function (e) {
1214 if ((jQuery("#validation_sequence").val() == "before") && (jQuery("#approve_status").val() == "wc-completed")) {
1215 if (!confirm("You have set to change the Approve Status to \"Completed\", and this will straightaway complete the order flow without sending to the payment gateway. Do you still want to continue?")) {
1216 jQuery("#approve_status").val("' . $approve_status . '");
1217 } else {
1218 e.preventDefault();
1219 }
1220 }
1221 });
1222
1223 jQuery("#validation_sequence").change(function (e) {
1224 if ((jQuery("#validation_sequence").val() == "before") && (jQuery("#approve_status").val() == "wc-completed")) {
1225 if (!confirm("You have set to change the Approve Status to \"Completed\", and this will straightaway complete the order flow without sending to the payment gateway. Do you still want to continue?")) {
1226 jQuery("#validation_sequence").val("' . $validation_sequence . '");
1227 } else {
1228 e.preventDefault();
1229 }
1230 }
1231 });
1232 </script>';
1233
1234 echo '
1235 <div class="wrap">
1236 <h1>FraudLabs Pro for WooCommerce</h1>
1237 ' . $form_status . '
1238 <form method="post" novalidate="novalidate">
1239 ' . wp_nonce_field('save-settings', '_wpnonce_save_settings') . '
1240 <div id="message" class="notice" style="border-left-color:#57b1f9;">
1241 <h3 style="margin-bottom:15px;">Quick Start Guide</h3>
1242 <p style="font-size:13px;margin-bottom:5px;"><b>👋 Just getting started?</b> &nbsp;Follow our <a href="https://www.fraudlabspro.com/supported-platforms/woocommerce" target="_blank">setup guide</a> to install and configure the plugin.</p>
1243 <p style="font-size:13px;margin-bottom:15px;"><b>🔍 Ready to explore?</b> &nbsp;Check out our <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-test-fraudlabs-pro-plugin-on-woocomerce/" target="_blank">usage guide</a> on how to use and test the plugin.</p>
1244 </div>
1245 ' . $this->admin_tabs() . '
1246 <div class="fraudlabspro-woocommece-tab-content">
1247 <table class="form-table">
1248 <tr>
1249 <td scope="row" colspan="2">
1250 <h2>Validation Settings</h2><hr />
1251 </td>
1252 </tr>
1253 <tr>
1254 <th scope="row">
1255 <label for="validation_sequence">Validation Trigger Point</label>
1256 </th>
1257 <td>
1258 <select name="validation_sequence" id="validation_sequence">
1259 <option value="after"' . ( ( $validation_sequence == 'after' ) ? ' selected' : '' ) . '> After submit order to payment gateway</option>
1260 <option value="before"' . ( ( $validation_sequence == 'before' ) ? ' selected' : '' ) . '> Before submit order to payment gateway</option>
1261 </select>
1262 <p class="description">
1263 You can choose to trigger the fraud validation either before or after the payment process. Please visit the <a href="https://www.fraudlabspro.com/resources/tutorials/what-is-validation-order-on-fraudlabspro-woocommerce/" target="_blank">Validation Trigger Point</a> article to learn more. <br /><br />
1264 <strong>Important Note: </strong> For the “Before submit order to payment gateway” option, the system will cancel the payment processing if it was rejected by FraudLabs Pro.
1265 </p>
1266 </td>
1267 </tr>
1268
1269 <tr id="enable_wc_advanced_velocity_tr">
1270 <th scope="row">
1271 <label for="enable_wc_fraudlabspro_advanced_velocity">Advanced Velocity Screening</label>
1272 </th>
1273 <td>
1274 <input type="checkbox" name="enable_wc_fraudlabspro_advanced_velocity" id="enable_wc_advanced_velocity"' . ( ( $enable_wc_fraudlabspro_advanced_velocity == 'yes' ) ? ' checked' : ( ( $validation_sequence == 'after' ) ? ' disabled' : '' ) ) . '>
1275 <p class="description">
1276 Enable advanced velocity screening that might consumes extra FraudLabs Pro credits. This option only available for <strong>Validation Trigger Point Before submit order to payment gateway</strong>. Please visit the <a href="https://www.fraudlabspro.com/resources/tutorials/what-is-advanced-velocity-screening-in-fraudlabs-pro-for-woocommerce-plugin/" target="_blank">Advanced Velocity Screening</a> article to learn more.
1277 </p>
1278 </td>
1279 </tr>
1280
1281 <tr>
1282 <th scope="row">
1283 <label for="manage_rules">Validation Rules</label>
1284 </th>
1285 <td>
1286 <input type="button" name="button" id="button-merchant-rule" class="button button-primary" value="Login to Merchant Area Rule Page" style="margin-top:5px; margin-bottom:5px;"/>
1287 <p class="description">
1288 You will need to login to merchant area to view and configure the validation rules.
1289 </p>
1290 </td>
1291 </tr>
1292 <tr>
1293 <td scope="row" colspan="2">
1294 <h2>WooCommerce Order Settings</h2><hr />
1295 </td>
1296 </tr>
1297 <tr>
1298 <th scope="row">
1299 <label for="approve_status">Approve Status</label>
1300 </th>
1301 <td>
1302 <select name="approve_status" id="approve_status">
1303 ';
1304
1305 foreach ( $wc_order_statuses as $key => $status ) {
1306 echo '
1307 <option value="' . $key . '"' . ( ( $approve_status == $key ) ? ' selected' : '' ) . '> ' . esc_html($status) . '</option>';
1308 }
1309
1310 echo '
1311 </select>
1312 <p class="description">
1313 Change to this order status if the order has been approved either by FraudLabs Pro, or via manual action.
1314 </p>
1315 </td>
1316 </tr>
1317
1318 <tr>
1319 <th scope="row">
1320 <label for="review_status">Review Status</label>
1321 </th>
1322 <td>
1323 <select name="review_status" id="review_status">';
1324
1325 foreach ( $wc_order_statuses as $key => $status ) {
1326 echo '
1327 <option value="' . $key . '"' . ( ( $review_status == $key ) ? ' selected' : '' ) . '> ' . $status . '</option>';
1328 }
1329
1330 echo '
1331 </select>
1332 <p class="description">
1333 Change to this order status if the order has been marked as <strong>REVIEW</strong> by FraudLabs Pro.
1334 </p>
1335 </td>
1336 </tr>
1337
1338 <tr>
1339 <th scope="row">
1340 <label for="reject_status">Reject Status</label>
1341 </th>
1342 <td>
1343 <select name="reject_status" id="reject_status">
1344 ';
1345
1346 foreach ( $wc_order_statuses as $key => $status ) {
1347 echo '
1348 <option value="' . $key . '"' . ( ( $reject_status == $key ) ? ' selected' : '' ) . '> ' . $status . '</option>';
1349 }
1350
1351 echo '
1352 </select>
1353 <p class="description">
1354 Change to this order status if the order has been rejected either by FraudLabs Pro, or via manual action.
1355 </p>
1356 </td>
1357 </tr>
1358
1359 <tr>
1360 <th scope="row">
1361 <label for="db_err_status">Internal Error Status</label>
1362 </th>
1363 <td>
1364 <select name="db_err_status" id="db_err_status">';
1365
1366 foreach ( $wc_order_statuses as $key => $status ) {
1367 echo '
1368 <option value="' . $key . '"' . ( ( $db_err_status == $key ) ? ' selected' : '' ) . '> ' . $status . '</option>';
1369 }
1370
1371 echo '
1372 </select>
1373 <p class="description">
1374 Change to this order status if FraudLabs Pro fails to perform the fraud validation due to internal errors.
1375 </p>
1376 </td>
1377 </tr>
1378
1379 <tr>
1380 <th scope="row">
1381 <label for="enable_wc_fraudlabspro_auto_change_status">Sync WooCommerce Completed/Cancelled Status</label>
1382 </th>
1383 <td>
1384 <input type="checkbox" name="enable_wc_fraudlabspro_auto_change_status" id="enable_wc_fraudlabspro_auto_change_status"' . ( ( $enable_wc_fraudlabspro_auto_change_status == 'yes' ) ? ' checked' : '' ) . '>
1385 <p class="description">
1386 When enabled, syncs WooCommerce order status back to FraudLabs Pro: <strong>Completed</strong> maps to <strong>Approve</strong> and <strong>Cancelled</strong> maps to <strong>Reject</strong>. Please visit this <a href="https://www.fraudlabspro.com/resources/tutorials/what-is-automated-order-approval-rejection-in-fraudlabs-pro-for-woocommerce-plugin/" target="_blank">article</a> for the detailed explanation.
1387 </p>
1388 </td>
1389 </tr>
1390
1391 <tr>
1392 <th scope="row">
1393 <label for="enable_wc_fraudlabspro_reject_fail_status">Reject WooCommerce Failed Order</label>
1394 </th>
1395 <td>
1396 <input type="checkbox" name="enable_wc_fraudlabspro_reject_fail_status" id="enable_wc_fraudlabspro_reject_fail_status"' . ( ( $enable_wc_fraudlabspro_reject_fail_status == 'yes' ) ? ' checked' : '' ) . '>
1397 <p class="description">
1398 Automatically reject orders in a Failed status to prevent further processing or fulfillment of potentially invalid or declined transactions.
1399 </p>
1400 </td>
1401 </tr>
1402
1403 <tr id="fraud_message_tr">
1404 <th scope="row">
1405 <label for="fraud_message">Fraud Message</label>
1406 </th>
1407 <td>
1408 <textarea name="fraud_message" id="fraud_message" class="large-text" rows="3" ' . ( ( $validation_sequence == 'after' ) ? ' disabled' : '' ) . '>' . $fraud_message . '</textarea>
1409 <p class="description">
1410 Display this message to customer if the order has been rejected by FraudLabs Pro. Please visit the <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-custom-the-fraud-message-for-woocommerce-display/" target="_blank">Fraud Message</a> article to learn more. This option only available for <strong>Validation Trigger Point Before submit order to payment gateway</strong>.
1411 </p>
1412 </td>
1413 </tr>
1414
1415 <tr>
1416 <th scope="row">
1417 <label for="real_ip_detection">Real IP Detection</label>
1418 </th>
1419 <td>
1420 <select name="real_ip_detect" id="real_ip_detect">
1421 <option value="no_override"' . ( ( $real_ip_detect == 'no_override' ) ? ' selected' : '' ) . '>No Override</option>
1422 <option value="remote_addr"' . ( ( $real_ip_detect == 'remote_addr' ) ? ' selected' : '' ) . '>REMOTE_ADDR</option>
1423 <option value="http_cf_connecting_ip"' . ( ( $real_ip_detect == 'http_cf_connecting_ip' ) ? ' selected' : '' ) . '>HTTP_CF_CONNECTING_IP</option>
1424 <option value="http_client_ip"' . ( ( $real_ip_detect == 'http_client_ip' ) ? ' selected' : '' ) . '>HTTP_CLIENT_IP</option>
1425 <option value="http_forwarded"' . ( ( $real_ip_detect == 'http_forwarded' ) ? ' selected' : '' ) . '>HTTP_FORWARDED</option>
1426 <option value="http_incap_client_ip"' . ( ( $real_ip_detect == 'http_incap_client_ip' ) ? ' selected' : '' ) . '>HTTP_INCAP_CLIENT_IP</option>
1427 <option value="http_x_forwarded"' . ( ( $real_ip_detect == 'http_x_forwarded' ) ? ' selected' : '' ) . '>HTTP_X_FORWARDED</option>
1428 <option value="http_x_forwarded_for"' . ( ( $real_ip_detect == 'http_x_forwarded_for' ) ? ' selected' : '' ) . '>HTTP_X_FORWARDED_FOR</option>
1429 <option value="http_x_real_ip"' . ( ( $real_ip_detect == 'http_x_real_ip' ) ? ' selected' : '' ) . '>HTTP_X_REAL_IP</option>
1430 <option value="http_x_sucuri_clientip"' . ( ( $real_ip_detect == 'http_x_sucuri_clientip' ) ? ' selected' : '' ) . '>HTTP_X_SUCURI_CLIENTIP</option>
1431 </select>
1432 <p class="description">
1433 If your WooCommerce is behind a reverse proxy or load balancer, use this option to choose the correct header for the real visitor IP detected by FraudLabs Pro.
1434 </p>
1435 </td>
1436 </tr>
1437
1438 <tr>
1439 <th scope="row">
1440 <label for="test_ip">Test IP</label>
1441 </th>
1442 <td>
1443 <input type="text" name="test_ip" id="test_ip" maxlength="15" value="' . $test_ip . '" class="regular-text code" />
1444 <p class="description">
1445 Simulate visitor IP address. Leave this field blank for live mode.
1446 </p>
1447 </td>
1448 </tr>
1449 <tr>
1450 <td scope="row" colspan="2">
1451 <h2>Plugin Settings</h2><hr />
1452 </td>
1453 </tr>
1454
1455 <tr>
1456 <th scope="row">
1457 <label for="enable_wc_fraudlabspro_report_expand">Expanded View</label>
1458 </th>
1459 <td>
1460 <input type="checkbox" name="enable_wc_fraudlabspro_report_expand" id="enable_wc_fraudlabspro_report_expand"' . ( ( $enable_wc_fraudlabspro_report_expand == 'yes' ) ? ' checked' : '' ) . '>
1461 <p class="description">Display the FraudLabs Pro report in expanded mode on Order Details page. By default, the report is in expanded mode.</p>
1462 </td>
1463 </tr>
1464
1465 <tr>
1466 <th scope="row">
1467 <label for="enable_wc_fraudlabspro_debug_log">Enable Debug Log</label>
1468 </th>
1469 <td>
1470 <input type="checkbox" name="enable_wc_fraudlabspro_debug_log" id="enable_wc_fraudlabspro_debug_log"' . ( ( $enable_wc_fraudlabspro_debug_log == 'yes' ) ? ' checked' : '' ) . '>
1471 </td>
1472 </tr>
1473
1474 <tr>
1475 <th scope="row">
1476 <label for="wc_fraudlabspro_debug_log_path">Debug Log Path</label>
1477 </th>
1478 <td>
1479 <input type="text" name="wc_fraudlabspro_debug_log_path" id="wc_fraudlabspro_debug_log_path" style="width:50% !important;" value="' . $wc_fraudlabspro_debug_log_path . '" class="regular-text"' . ( ( $enable_wc_fraudlabspro_debug_log != 'yes' ) ? ' disabled' : '' ) . ' placeholder="/wp-content/plugins/fraudlabs-pro-for-woocommerce/" />
1480 <p class="description">
1481 The path to store the debug log file. Leave this field blank for default log path which located in the fraudlabs-pro-for-woocommerce plugin folder.
1482 </p>
1483 </td>
1484 </tr>';
1485
1486 $filePath = ( ( get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') != '' ) ? ABSPATH . get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') . 'debug.log' : ABSPATH . '/wp-content/plugins/fraudlabs-pro-for-woocommerce/debug.log' );
1487 $file = ( ( get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') != '' ) ? get_site_url() . get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') . 'debug.log' : get_site_url() . '/wp-content/plugins/fraudlabs-pro-for-woocommerce/debug.log' );
1488 if (is_writable($filePath)) {
1489 $file_headers = @get_headers($file);
1490 if ( strpos( $file_headers[0], "OK" ) !== false ) {
1491 echo '
1492 <tr>
1493 <th scope="row">
1494 </th>
1495 <td>
1496 <a href="' . $file . '" download="debug.log"><input type="button" name="button" id="button-download-log" class="button" value="Download Debug Log File" /></a>
1497 </td>
1498 </tr>';
1499 }
1500 }
1501 echo '
1502 </table>
1503 <p class="submit">
1504 <input type="hidden" name="form_order_submitted" value="" />
1505 <input style="padding:3px 16px; font-size:13px;" type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes" />
1506 </p>
1507 </div>
1508 </form>
1509 </div>
1510 ';
1511 break;
1512
1513 case 'notification':
1514 $notification_on_approve = ( isset( $_POST['submit'] ) && isset( $_POST['notification_on_approve'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['notification_on_approve'] ) ) ) ? 'no' : $this->get_setting( 'notification_approve' ) );
1515 $notification_on_review = ( isset( $_POST['submit'] ) && isset( $_POST['notification_on_review'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['notification_on_review'] ) ) ) ? 'no' : $this->get_setting( 'notification_review' ) );
1516 $notification_on_reject = ( isset( $_POST['submit'] ) && isset( $_POST['notification_on_reject'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['notification_on_reject'] ) ) ) ? 'no' : $this->get_setting( 'notification_reject' ) );
1517
1518 $form_status = '';
1519
1520 if ( isset( $_POST['submit'] ) ) {
1521 check_admin_referer('save-settings', '_wpnonce_save_settings');
1522
1523 if ( empty( $form_status ) ) {
1524 $this->update_setting( 'notification_approve', $notification_on_approve );
1525 $this->update_setting( 'notification_review', $notification_on_review );
1526 $this->update_setting( 'notification_reject', $notification_on_reject );
1527
1528 $form_status = '
1529 <div id="message" class="updated">
1530 <p>Changes saved.</p>
1531 </div>';
1532 }
1533 }
1534
1535 echo '
1536 <div class="wrap">
1537 <h1>FraudLabs Pro for WooCommerce</h1>
1538 ' . $form_status . '
1539 <form method="post" novalidate="novalidate">
1540 ' . wp_nonce_field('save-settings', '_wpnonce_save_settings') . '
1541 <div id="message" class="notice" style="border-left-color:#57b1f9;">
1542 <h3 style="margin-bottom:15px;">Quick Start Guide</h3>
1543 <p style="font-size:13px;margin-bottom:5px;"><b>👋 Just getting started?</b> &nbsp;Follow our <a href="https://www.fraudlabspro.com/supported-platforms/woocommerce" target="_blank">setup guide</a> to install and configure the plugin.</p>
1544 <p style="font-size:13px;margin-bottom:15px;"><b>🔍 Ready to explore?</b> &nbsp;Check out our <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-test-fraudlabs-pro-plugin-on-woocomerce/" target="_blank">usage guide</a> on how to use and test the plugin.</p>
1545 </div>
1546 ' . $this->admin_tabs() . '
1547 <div class="fraudlabspro-woocommece-tab-content">
1548 <table class="form-table">
1549 <tr>
1550 <td scope="row" colspan="2">
1551 <h2>Notification</h2><hr />
1552 </td>
1553 </tr>
1554
1555 <tr>
1556 <th scope="row">
1557 <label for="notification_status">Email Notification</label>
1558 </th>
1559 <td>
1560 <p>
1561 Please login to <a href="https://www.fraudlabspro.com/merchant/setting" target="_blank">merchant area</a> to configure the email notification under the Settings page.
1562 </p>
1563 </td>
1564 </tr>
1565
1566 <tr>
1567 <th scope="row">
1568 <label for="notification_status">Zapier Notification</label>
1569 </th>
1570 <td>
1571 <p>
1572 <input type="checkbox" name="notification_on_approve" id="notification_on_approve"' . ( ( $notification_on_approve == 'yes' ) ? ' checked' : '' ) . '> Approve Status
1573 </p>
1574 <p>
1575 <input type="checkbox" name="notification_on_review" id="notification_on_review"' . ( ( $notification_on_review == 'yes' ) ? ' checked' : '' ) . '> Review Status
1576 </p>
1577 <p>
1578 <input type="checkbox" name="notification_on_reject" id="notification_on_reject"' . ( ( $notification_on_reject == 'yes' ) ? ' checked' : '' ) . '> Reject Status
1579 </p>
1580 <p class="description">
1581 You can trigger notification, such as email sending, using the Zapier service. Please configure the integration in Zapier.com before enabling this option. You can visit the <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-enable-notification-using-zapier-in-woocommerce/" target="_blank">How to Enable Notification Using Zapier</a> article to learn more.
1582 </p>
1583 </td>
1584 </tr>
1585 </table>
1586 <p class="submit">
1587 <input type="hidden" name="form_notification_submitted" value="" />
1588 <input style="padding:3px 16px; font-size:13px;" type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes" />
1589 </p>
1590 </div>
1591 </form>
1592 </div>';
1593 break;
1594
1595 case 'data':
1596 if ( isset( $_POST['purge'] ) ) {
1597 check_admin_referer('purge-data', '_wpnonce_purge_data');
1598
1599 global $wpdb;
1600 $wpdb->query('DELETE FROM ' . $wpdb->prefix . 'postmeta WHERE meta_key LIKE "%fraudlabspro%"');
1601 $wpdb->query('TRUNCATE `' . $wpdb->prefix . 'fraudlabspro_wc`');
1602 $form_status = '
1603 <div id="message" class="updated">
1604 <p>All data have been deleted.</p>
1605 </div>';
1606 }
1607 echo '
1608 <div class="wrap">
1609 <h1>FraudLabs Pro for WooCommerce</h1>
1610 <div id="message" class="notice" style="border-left-color:#57b1f9;">
1611 <h3 style="margin-bottom:15px;">Quick Start Guide</h3>
1612 <p style="font-size:13px;margin-bottom:5px;"><b>👋 Just getting started?</b> &nbsp;Follow our <a href="https://www.fraudlabspro.com/supported-platforms/woocommerce" target="_blank">setup guide</a> to install and configure the plugin.</p>
1613 <p style="font-size:13px;margin-bottom:15px;"><b>🔍 Ready to explore?</b> &nbsp;Check out our <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-test-fraudlabs-pro-plugin-on-woocomerce/" target="_blank">usage guide</a> on how to use and test the plugin.</p>
1614 </div>
1615 ' . $this->admin_tabs() . '
1616 <div class="fraudlabspro-woocommece-tab-content">
1617 <p>
1618 <form id="form-purge" method="post">
1619 <h2>Data Management</h2><hr />
1620 <input type="hidden" name="purge" value="true">
1621 <p>Remove <strong>all FraudLabs Pro data</strong> from your local storage (WordPress). Please note that this action is not reversible!</p>
1622 <input type="button" name="button" id="button-purge" class="button" style="background-color:red; color:white;" value="Delete All Data" />
1623 ' . wp_nonce_field('purge-data', '_wpnonce_purge_data') . '
1624 </form>
1625 </p>
1626 </div>
1627 </div>
1628 ';
1629 break;
1630
1631 case 'settings':
1632 default:
1633 $plan_name = '';
1634 $plan_upgrade = '';
1635 $credit_display = '';
1636 $credit_warning = '';
1637 // Use plan API to get license information
1638 $request = wp_remote_get( 'https://api.fraudlabspro.com/v2/plan/result?' . http_build_query( array(
1639 'key' => $this->api_key,
1640 'format' => 'json',
1641 'timestamp' => time()
1642 ) ) );
1643
1644 if ( ! is_wp_error( $request ) ) {
1645 // Get the HTTP response
1646 $response = json_decode( wp_remote_retrieve_body( $request ) );
1647
1648 if ( is_object( $response ) ) {
1649 $plan_name = $response->plan_name;
1650 $credit_available = $response->query_limit - $response->query_limit_used;
1651 $next_renewal_date = $response->next_renewal_date;
1652 $plan_upgrade = (($plan_name != 'FraudLabs Pro Enterprise') ? '<input type="button" name="button" id="button-upgrade" class="button button-outline-primary" value="Explore More Plans" style="margin-left:20px;" />' : '');
1653
1654 if (($plan_name == 'FraudLabs Pro Micro') && ($credit_available <= 100)){
1655 $credit_display = 'color:red;';
1656 $credit_warning = 'You are going to run out of credits, you should <a href="https://www.fraudlabspro.com/pricing" target="_blank">upgrade</a> now to avoid service disruptions.';
1657 } elseif ($credit_available <= 100) {
1658 $credit_display = 'color:red;';
1659 $credit_warning = '';
1660 } else {
1661 $credit_display = $credit_warning = '';
1662 }
1663 }
1664 }
1665
1666 $form_status = '';
1667
1668 $enable_wc_fraudlabspro = ( isset( $_POST['submit'] ) && isset( $_POST['enable_wc_fraudlabspro'] ) ) ? 'yes' : ( ( ( isset( $_POST['submit'] ) && !isset( $_POST['enable_wc_fraudlabspro'] ) ) ) ? 'no' : $this->get_setting( 'enabled' ) );
1669 $api_key = ( isset( $_POST['api_key'] ) ) ? sanitize_text_field(esc_attr($_POST['api_key'])) : $this->get_setting( 'api_key' );
1670
1671 if ( isset( $_POST['submit'] ) ) {
1672 check_admin_referer('save-settings', '_wpnonce_save_settings');
1673
1674 if ( !preg_match( '/^[0-9A-Z]{32}$/', $api_key ) ) {
1675 $api_key = '';
1676 $form_status .= '
1677 <div id="message" class="error">
1678 <p><strong>ERROR</strong>: Please enter a valid FraudLabs Pro API key.</p>
1679 </div>';
1680 }
1681
1682 if ( empty( $form_status ) ) {
1683 $this->update_setting( 'enabled', $enable_wc_fraudlabspro );
1684 $this->update_setting( 'api_key', $api_key );
1685
1686 if ( $api_key !== $this->api_key ) {
1687 // Use plan API to get license information
1688 $request = wp_remote_get( 'https://api.fraudlabspro.com/v2/plan/result?' . http_build_query( array(
1689 'key' => $api_key,
1690 'format' => 'json'
1691 ) ) );
1692
1693 if ( ! is_wp_error( $request ) ) {
1694 // Get the HTTP response
1695 $response = json_decode( wp_remote_retrieve_body( $request ) );
1696
1697 if ( is_object( $response ) ) {
1698 $plan_name = $response->plan_name;
1699 $credit_available = $response->query_limit - $response->query_limit_used;
1700 $next_renewal_date = $response->next_renewal_date;
1701
1702 if (($plan_name == 'FraudLabs Pro Micro') && ($credit_available <= 100)){
1703 $credit_display = 'color:red;';
1704 $credit_warning = 'You are going to run out of credits, you should <a href="https://www.fraudlabspro.com/pricing" target="_blank">upgrade</a> now to avoid service disruptions.';
1705 } elseif ($credit_available <= 100) {
1706 $credit_display = 'color:red;';
1707 $credit_warning = '';
1708 } else {
1709 $credit_display = $credit_warning = '';
1710 }
1711 }
1712 }
1713 }
1714
1715 $form_status = '
1716 <div id="message" class="updated">
1717 <p>Changes saved.</p>
1718 </div>';
1719 }
1720 }
1721
1722 echo '
1723 <script>
1724 jQuery(document).ready(function($) {
1725 $("#button-merchant").on("click", function(e) {
1726 window.open("https://www.fraudlabspro.com/merchant/login", "_blank");
1727 });
1728
1729 $("#button-merchant-rule").on("click", function(e) {
1730 window.open("https://www.fraudlabspro.com/merchant/rule", "_blank");
1731 });
1732
1733 $("#button-upgrade").on("click", function(e) {
1734 var plan_name = "' . $plan_name . '";
1735 switch (plan_name) {
1736 case "FraudLabs Pro Micro":
1737 window.open("https://www.fraudlabspro.com/subscribe?id=8", "_blank");
1738 break;
1739
1740 case "FraudLabs Pro Mini":
1741 window.open("https://www.fraudlabspro.com/subscribe?id=2", "_blank");
1742 break;
1743
1744 case "FraudLabs Pro Small":
1745 window.open("https://www.fraudlabspro.com/subscribe?id=3", "_blank");
1746 break;
1747
1748 case "FraudLabs Pro Medium":
1749 window.open("https://www.fraudlabspro.com/subscribe?id=4", "_blank");
1750 break;
1751
1752 case "FraudLabs Pro Large":
1753 window.open("https://www.fraudlabspro.com/subscribe?id=5", "_blank");
1754 break;
1755
1756 default:
1757 window.open("https://www.fraudlabspro.com/pricing", "_blank");
1758 break;
1759 }
1760 });
1761 });
1762 </script>';
1763
1764 echo '
1765 <div class="wrap">
1766 <h1>FraudLabs Pro for WooCommerce</h1>
1767 ' . $form_status . '
1768 <form method="post" novalidate="novalidate">
1769 ' . wp_nonce_field('save-settings', '_wpnonce_save_settings') . '
1770 <div id="message" class="notice" style="border-left-color:#57b1f9;">
1771 <h3 style="margin-bottom:15px;">Quick Start Guide</h3>
1772 <p style="font-size:13px;margin-bottom:5px;"><b>👋 Just getting started?</b> &nbsp;Follow our <a href="https://www.fraudlabspro.com/supported-platforms/woocommerce" target="_blank">setup guide</a> to install and configure the plugin.</p>
1773 <p style="font-size:13px;margin-bottom:15px;"><b>🔍 Ready to explore?</b> &nbsp;Check out our <a href="https://www.fraudlabspro.com/resources/tutorials/how-to-test-fraudlabs-pro-plugin-on-woocomerce/" target="_blank">usage guide</a> on how to use and test the plugin.</p>
1774 </div>
1775 ' . $this->admin_tabs() . '
1776 <div class="fraudlabspro-woocommece-tab-content">
1777 <table class="form-table">
1778 <tr>
1779 <td scope="row" colspan="2">
1780 <h2>General Settings </h2><hr />
1781 </td>
1782 </tr>
1783 <tr>
1784 <th scope="row">
1785 <label for="enable_wc_fraudlabspro">Enable FraudLabs Pro Validation</label>
1786 </th>
1787 <td>
1788 <input type="checkbox" name="enable_wc_fraudlabspro" id="enable_wc_fraudlabspro"' . ( ( $enable_wc_fraudlabspro == 'yes' ) ? ' checked' : '' ) . '>
1789 </td>
1790 </tr>
1791 <tr>
1792 <td scope="row" colspan="2">
1793 <h2>License Information</h2><hr />
1794 </td>
1795 </tr>
1796
1797 <tr>
1798 <th scope="row">
1799 <label for="plan_name">Plan Name</label>
1800 </th>
1801 <td>
1802 <p>' . esc_html($plan_name) . '</p>
1803 </td>
1804 </tr>
1805
1806 <tr>
1807 <th scope="row">
1808 <label for="credit_available">Credit Available</label>
1809 </th>
1810 <td>
1811 <p style=' . $credit_display . '>' . number_format((int)$credit_available, false, false, ",") . '</p><p class="description"><strong>' . $credit_warning . '</strong></p>
1812 </td>
1813 </tr>
1814
1815 <tr>
1816 <th scope="row">
1817 <label for="next_renewal_date">Next Renewal Date</label>
1818 </th>
1819 <td>
1820 <p>' . esc_html($next_renewal_date) . '</p>
1821 </td>
1822 </tr>
1823
1824 <tr>
1825 <th scope="row">
1826 <label for="api_key">API Key</label>
1827 </th>
1828 <td>
1829 <input type="text" name="api_key" id="api_key" maxlength="32" value="' . $api_key . '" class="regular-text code" />
1830 <p class="description">
1831 You can sign up for a free API key at <a href="https://www.fraudlabspro.com/subscribe?id=1#woocommerce-pltstg" target="_blank">FraudLabs Pro</a>.
1832 </p>
1833 </td>
1834 </tr>
1835 </table>
1836
1837 <p style="margin-top:15px;font-size:14px;">To manage your account settings, view fraud reports, or adjust validation rules:</p>
1838 <a style="font-size:14px;" href="https://www.fraudlabspro.com/merchant/login" target="_blank">Login to Your Merchant Area >></a>
1839
1840 <p style="font-size:14px;">To unlock more advanced features for fraud protection:</p>
1841 <a style="font-size:14px;" href="https://www.fraudlabspro.com/pricing" target="_blank">Explore More Plans >></a>
1842
1843 <p style="margin-top:35px;">
1844 <input style="padding:3px 16px; font-size:13px;" type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes" />
1845 </p>
1846 </div>
1847 </form>
1848 </div>';
1849 }
1850 }
1851
1852 /**
1853 * Create admin tab.
1854 */
1855 private function admin_tabs()
1856 {
1857 $disable_tabs = false;
1858 $tab = (isset($_GET['tab'])) ? sanitize_text_field($_GET['tab']) : 'settings';
1859
1860 return '
1861 <h2 class="nav-tab-wrapper fraudlabspro-woocommerce-wrapper">
1862 <a href="' . (($disable_tabs) ? 'javascript:;' : admin_url('admin.php?page=woocommerce-fraudlabs-pro&tab=settings')) . '" class="nav-tab' . (($tab == 'settings') ? ' nav-tab-active' : '') . '" style="margin-left:0;">General</a>
1863 <a href="' . (($disable_tabs) ? 'javascript:;' : admin_url('admin.php?page=woocommerce-fraudlabs-pro&tab=order')) . '" class="nav-tab' . (($tab == 'order') ? ' nav-tab-active' : '') . '">Order</a>
1864 <a href="' . (($disable_tabs) ? 'javascript:;' : admin_url('admin.php?page=woocommerce-fraudlabs-pro&tab=notification')) . '" class="nav-tab' . (($tab == 'notification') ? ' nav-tab-active' : '') . '">Notification</a>
1865 <a href="' . (($disable_tabs) ? 'javascript:;' : admin_url('admin.php?page=woocommerce-fraudlabs-pro&tab=data')) . '" class="nav-tab' . (($tab == 'data') ? ' nav-tab-active' : '') . '">Data</a>
1866 </h2>';
1867 }
1868
1869 /**
1870 * Javascript agent.
1871 */
1872 public function javascript_agent() {
1873 if (is_checkout()) {
1874 echo '<script>!function(){function t(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://cdn.fraudlabspro.com/s.js";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(t,e)}window.attachEvent?window.attachEvent("onload",t):window.addEventListener("load",t,!1)}();</script>';
1875 }
1876 }
1877
1878
1879 /**
1880 * Add risk score column to order list.
1881 */
1882 public function add_column( $columns ) {
1883 if ( $this->enabled != 'yes' ) {
1884 return $columns;
1885 }
1886
1887 $columns = array_merge( array_slice( $columns, 0, 5 ), array( 'fraudlabspro_score' => 'Risk Score' ), array_slice( $columns, 5 ) );
1888 return $columns;
1889 }
1890
1891
1892 /**
1893 * Add risk score column to order list for HPOS.
1894 */
1895 public function add_column_hpos( $columns ) {
1896 if ( $this->enabled != 'yes' ) {
1897 return $columns;
1898 }
1899
1900 $columns = array_merge( array_slice( $columns, 0, 5 ), array( 'fraudlabspro_score' => 'Risk Score' ), array_slice( $columns, 5 ) );
1901 return $columns;
1902 }
1903
1904
1905 /**
1906 * Fill in FraudLabs Pro score into risk score column.
1907 */
1908 public function render_column( $column ) {
1909 if ( $this->enabled != 'yes' ) {
1910 return;
1911 }
1912
1913 if ( $column != 'fraudlabspro_score' ) {
1914 return;
1915 }
1916
1917 global $post;
1918
1919 $result = get_post_meta( $post->ID, '_fraudlabspro' );
1920
1921 if (!$result) {
1922 $table_name = $this->create_flpwc_table();
1923 $result = $this->get_flpwc_data($table_name, $post->ID, '_fraudlabspro');
1924 }
1925
1926 if ( count( $result ) > 0 ) {
1927 $idx = count( $result ) - 1;
1928 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) && strpos( $result[$idx], '\\' ) ) {
1929 $result[$idx] = str_replace( '\\', '', $result[$idx] );
1930 }
1931
1932 if( is_array( $result[$idx] ) ){
1933 if ( is_null( $row = $result[$idx] ) === FALSE ) {
1934 if ( isset( $row['fraudlabspro_score'] ) ) {
1935 if ( $row['fraudlabspro_score'] > 80 ) {
1936 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#ff0000"><span class="dashicons dashicons-warning"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
1937 }
1938 elseif ( $row['fraudlabspro_score'] > 60 ) {
1939 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#f0c850"><span class="dashicons dashicons-warning"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
1940 }
1941 else {
1942 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#66cc00"><span class="dashicons dashicons-thumbs-up"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
1943 }
1944 }
1945 }
1946 } else {
1947 if( is_object( $result[$idx] ) ){
1948 $row = $result[$idx];
1949 } else {
1950 $row = json_decode( $result[$idx] );
1951 }
1952 if ( is_null( $row ) === FALSE ) {
1953 if ( isset( $row->fraudlabspro_score ) ) {
1954 if ( $row->fraudlabspro_score > 80 ) {
1955 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#ff0000"><span class="dashicons dashicons-warning"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
1956 }
1957 elseif ( $row->fraudlabspro_score > 60 ) {
1958 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#f0c850"><span class="dashicons dashicons-warning"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
1959 }
1960 else {
1961 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $post->ID . '&action=edit#flp-details"><div style="color:#66cc00"><span class="dashicons dashicons-thumbs-up"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
1962 }
1963 }
1964 }
1965 }
1966 }
1967 }
1968
1969 /**
1970 * Fill in FraudLabs Pro score into risk score column for HPOS.
1971 */
1972 public function render_column_hpos( $column, $order ) {
1973 if ( $this->enabled != 'yes' ) {
1974 return;
1975 }
1976
1977 if ( $column != 'fraudlabspro_score' ) {
1978 return;
1979 }
1980
1981 $result = get_post_meta( $order->get_id(), '_fraudlabspro' );
1982
1983 if (!$result) {
1984 $table_name = $this->create_flpwc_table();
1985 $result = $this->get_flpwc_data($table_name, $order->get_id(), '_fraudlabspro');
1986 }
1987
1988 if ( count( $result ) > 0 ) {
1989 $idx = count( $result ) - 1;
1990 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) && strpos( $result[$idx], '\\' ) ) {
1991 $result[$idx] = str_replace( '\\', '', $result[$idx] );
1992 }
1993
1994 if( is_array( $result[$idx] ) ){
1995 if ( is_null( $row = $result[$idx] ) === FALSE ) {
1996 if ( isset( $row['fraudlabspro_score'] ) ) {
1997 if ( $row['fraudlabspro_score'] > 80 ) {
1998 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#ff0000"><span class="dashicons dashicons-warning"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
1999 }
2000 elseif ( $row['fraudlabspro_score'] > 60 ) {
2001 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#f0c850"><span class="dashicons dashicons-warning"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
2002 }
2003 else {
2004 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#66cc00"><span class="dashicons dashicons-thumbs-up"></span> <strong>' . $row['fraudlabspro_score'] . '</strong></div></a>';
2005 }
2006 }
2007 }
2008 } else {
2009 if( is_object( $result[$idx] ) ){
2010 $row = $result[$idx];
2011 } else {
2012 $row = json_decode( $result[$idx] );
2013 }
2014 if ( is_null( $row ) === FALSE ) {
2015 if ( isset( $row->fraudlabspro_score ) ) {
2016 if ( $row->fraudlabspro_score > 80 ) {
2017 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#ff0000"><span class="dashicons dashicons-warning"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
2018 }
2019 elseif ( $row->fraudlabspro_score > 60 ) {
2020 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#f0c850"><span class="dashicons dashicons-warning"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
2021 }
2022 else {
2023 echo '<a href="' . get_site_url() . '/wp-admin/post.php?post=' . $order->get_id() . '&action=edit#flp-details"><div style="color:#66cc00"><span class="dashicons dashicons-thumbs-up"></span> <strong>' . $row->fraudlabspro_score . '</strong></div></a>';
2024 }
2025 }
2026 }
2027 }
2028 }
2029 }
2030
2031
2032 /**
2033 * Append FraudLabs Pro report to order details.
2034 */
2035 public function render_fraud_report() {
2036 if ( $this->enabled != 'yes' ) {
2037 return;
2038 }
2039
2040 wp_enqueue_script( 'jquery' );
2041
2042 // Checking for HPOS
2043 if ( isset( $_GET['id'] ) ) {
2044 $_GET['post'] = $_GET['id'];
2045 }
2046
2047 if ( isset( $_POST['orderId'] ) ) {
2048 $order = wc_get_order( sanitize_text_field($_POST['orderId']) );
2049 }
2050
2051 if ( isset( $_POST['approve-flp'] ) ) {
2052 check_admin_referer('review-action', '_wpnonce_review_flp');
2053
2054 $queries = [
2055 'key' => $this->api_key,
2056 'action' => 'APPROVE',
2057 'id' => sanitize_text_field($_POST['transactionId']),
2058 'format' => 'json',
2059 'source' => 'woocommerce',
2060 'triggered_by' => 'manual'
2061 ];
2062 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/feedback', $queries );
2063
2064 if ( $request ) {
2065 $response = json_decode( $request );
2066
2067 if ( is_object( $response ) ) {
2068 $result = get_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro' );
2069
2070 if (!$result) {
2071 $table_name = $this->create_flpwc_table();
2072 $result = $this->get_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro');
2073 }
2074
2075 $idx = count( $result ) - 1;
2076 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2077 $row = json_decode( $result[$idx] );
2078 } else {
2079 $row = $result[$idx];
2080 }
2081
2082 if ( is_array( $result[$idx] ) ) {
2083 $row['fraudlabspro_status'] = 'APPROVE';
2084 } else {
2085 if (isset($row->fraudlabspro_status)) {
2086 $row->fraudlabspro_status = 'APPROVE';
2087 }
2088 }
2089 update_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro', $row );
2090 $table_name = $this->create_flpwc_table();
2091 $this->update_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro', $row);
2092
2093 if( $this->approve_status && $order->get_status() != 'wc-completed' ) {
2094 $order->add_order_note( __( 'FraudLabs Pro status has been changed from Review to Approved. This order status has also been updated.', $this->namespace ) );
2095 $order->update_status( $this->approve_status, __( '', $this->namespace ) );
2096 wp_safe_redirect($_SERVER['REQUEST_URI']);
2097 exit;
2098 } else {
2099 //only add the note
2100 $order->add_order_note( __( 'FraudLabs Pro status has been changed from Review to Approved.', $this->namespace ) );
2101 wp_safe_redirect($_SERVER['REQUEST_URI']);
2102 exit;
2103 }
2104 }
2105 }
2106 }
2107
2108 if( isset( $_POST['reject-flp'] ) ) {
2109 check_admin_referer('review-action', '_wpnonce_review_flp');
2110
2111 $queries = [
2112 'key' => $this->api_key,
2113 'action' => 'REJECT',
2114 'id' => sanitize_text_field($_POST['transactionId']),
2115 'format' => 'json',
2116 'source' => 'woocommerce',
2117 'triggered_by' => 'manual'
2118 ];
2119 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/feedback', $queries );
2120
2121 if ( $request ) {
2122 $response = json_decode( $request );
2123
2124 if ( is_object( $response ) ) {
2125 $result = get_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro' );
2126
2127 if (!$result) {
2128 $table_name = $this->create_flpwc_table();
2129 $result = $this->get_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro');
2130 }
2131
2132 $idx = count( $result ) - 1;
2133 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2134 $row = json_decode( $result[$idx] );
2135 } else {
2136 $row = $result[$idx];
2137 }
2138
2139 if ( is_array( $result[$idx] ) ) {
2140 $row['fraudlabspro_status'] = 'REJECT';
2141 } else {
2142 if (isset($row->fraudlabspro_status)) {
2143 $row->fraudlabspro_status = 'REJECT';
2144 }
2145 }
2146 update_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro', $row );
2147 $table_name = $this->create_flpwc_table();
2148 $this->update_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro', $row);
2149
2150 if( $this->reject_status ) {
2151 $order->add_order_note( __( 'FraudLabs Pro status has been changed from Review to Rejected. This order status has also been updated.', $this->namespace ) );
2152 $order->update_status( $this->reject_status, __( '', $this->namespace ) );
2153 wp_safe_redirect($_SERVER['REQUEST_URI']);
2154 exit;
2155 } else {
2156 //just add the note
2157 $order->add_order_note( __( 'FraudLabs Pro status has been changed from Review to Rejected.', $this->namespace ) );
2158 wp_safe_redirect($_SERVER['REQUEST_URI']);
2159 exit;
2160 }
2161 }
2162 }
2163 }
2164
2165 $reject_blacklist = ( isset ( $_POST['new_status'] ) ) ? sanitize_text_field($_POST['new_status']) : '';
2166
2167 if ( $reject_blacklist === 'reject_blacklist') {
2168 check_admin_referer('review-action', '_wpnonce_review_flp');
2169
2170 $queries = [
2171 'key' => $this->api_key,
2172 'action' => 'REJECT_BLACKLIST',
2173 'id' => sanitize_text_field($_POST['transactionId']),
2174 'format' => 'json',
2175 'note' => sanitize_text_field($_POST['feedback_note']),
2176 'source' => 'woocommerce',
2177 'triggered_by' => 'manual'
2178 ];
2179 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/feedback', $queries );
2180
2181 if ( $request ) {
2182 $response = json_decode( $request );
2183
2184 if ( is_object( $response ) ) {
2185 $result = get_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro' );
2186
2187 if (!$result) {
2188 $table_name = $this->create_flpwc_table();
2189 $result = $this->get_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro');
2190 }
2191
2192 $idx = count( $result ) - 1;
2193 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2194 $row = json_decode( $result[$idx] );
2195 } else {
2196 $row = $result[$idx];
2197 }
2198
2199 if ( is_array( $result[$idx] ) ) {
2200 $row['fraudlabspro_status'] = 'REJECT';
2201 $row['is_blacklisted'] = '1';
2202 } else {
2203 if (isset($row->fraudlabspro_status)) {
2204 $row->fraudlabspro_status = 'REJECT';
2205 $row->is_blacklisted = '1';
2206 }
2207 }
2208 update_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro', $row );
2209 $table_name = $this->create_flpwc_table();
2210 $this->update_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro', $row);
2211
2212 if( $this->reject_status ) {
2213 $order->add_order_note( __( 'This order has been blacklisted by FraudLabs Pro and the order status has also been updated.', $this->namespace ) );
2214 $order->update_status( $this->reject_status, __( '', $this->namespace ) );
2215 wp_safe_redirect($_SERVER['REQUEST_URI']);
2216 exit;
2217 } else {
2218 //just add the note
2219 $order->add_order_note( __( 'This order has been blacklisted by FraudLabs Pro.', $this->namespace ) );
2220 wp_safe_redirect($_SERVER['REQUEST_URI']);
2221 exit;
2222 }
2223 }
2224 }
2225 }
2226
2227 $plan_name = '';
2228 // Use plan API to get license information
2229 $request = wp_remote_get( 'https://api.fraudlabspro.com/v2/plan/result?' . http_build_query( array(
2230 'key' => $this->api_key,
2231 'format' => 'json'
2232 ) ) );
2233
2234 if ( ! is_wp_error( $request ) ) {
2235 // Get the HTTP response
2236 $response = json_decode( wp_remote_retrieve_body( $request ) );
2237
2238 if ( is_object( $response ) ) {
2239 $plan_name = $response->plan_name;
2240 }
2241 }
2242
2243 if ( isset( $_GET['post'] ) ) {
2244 $result = get_post_meta( sanitize_text_field($_GET['post']), '_fraudlabspro' );
2245
2246 if (!$result) {
2247 $table_name = $this->create_flpwc_table();
2248 $result = $this->get_flpwc_data($table_name, sanitize_text_field($_GET['post']), '_fraudlabspro');
2249 }
2250
2251 if ( count( $result ) > 0 ) {
2252 $idx = count( $result ) - 1;
2253 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) && strpos( $result[$idx], '\\' ) ) {
2254 $result[$idx] = str_replace( '\\', '', $result[$idx] );
2255 }
2256
2257 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2258 $row = json_decode( $result[$idx] );
2259 } else {
2260 $row = $result[$idx];
2261 }
2262
2263 if( is_array( $result[$idx] ) ){
2264 if ( $row['fraudlabspro_id'] != '' ){
2265 $table = '
2266 <style type="text/css">
2267 .fraudlabspro {width:100%;}
2268 .fraudlabspro td{padding:10px 0; vertical-align:top}
2269 .flp-helper{text-decoration:none}
2270
2271 /* color: Approve - #45b6af, Reject - #f3565d, Review - #dfba49 */
2272 </style>
2273
2274 <table class="fraudlabspro">
2275 <tr>
2276 <td colspan="3" style="text-align:center; background-color:#ab1b1c; border:1px solid #ab1b1c; padding-top:10px; padding-bottom:10px;">
2277 <a href="https://www.fraudlabspro.com" target="_blank"><img src="'. plugins_url( '/assets/images/logo_200.png', WC_FLP_DIR ) .'" alt="FraudLabs Pro" /></a>
2278 </td>
2279 </tr>';
2280
2281 $location = array();
2282 if ( strlen( $row['ip_country'] ) == 2 ) {
2283 $location = array(
2284 $this->get_country_by_code( esc_html($row['ip_country']) ),
2285 esc_html($row['ip_region']),
2286 esc_html($row['ip_city'])
2287 );
2288
2289 $location = array_unique( $location );
2290 }
2291
2292 switch( $row['fraudlabspro_status'] ) {
2293 case 'REVIEW':
2294 $fraudlabspro_status_display = "REVIEW";
2295 $color = 'dfba49';
2296 break;
2297
2298 case 'REJECT':
2299 $fraudlabspro_status_display = "REJECTED";
2300 $color = 'f3565d';
2301 break;
2302
2303 case 'APPROVE':
2304 $fraudlabspro_status_display = "APPROVED";
2305 $color = '45b6af';
2306 break;
2307 }
2308
2309 $table .= '
2310 <tr>
2311 <td><p style="font-size:16px;margin: 0 auto;"><b>General</b></p></td>
2312 </tr>
2313 <tr>
2314 <td rowspan="2">
2315 <b>FraudLabs Pro Score</b> <a href="javascript:;" class="flp-helper" title="Risk score, 0 (low risk) - 100 (high risk)."><span class="dashicons dashicons-editor-help"></span></a><br/>
2316 <img class="img-responsive" alt="" src="//cdn.fraudlabspro.com/assets/img/scores/meter-' . ( ( $row['fraudlabspro_score'] ) ? esc_html($row['fraudlabspro_score']) . '.png' : 'nofraudprotection.png' ) . '" style="width:160px;" />
2317 </td>
2318 <td>
2319 <b>FraudLabs Pro Status</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro status."><span class="dashicons dashicons-editor-help"></span></a>
2320 <span style="color:#' . $color . ';font-size:28px; display:block;">' . $fraudlabspro_status_display . '</span>
2321 </td>
2322 <td>
2323 <b>Credit Balance</b> <a href="javascript:;" class="flp-helper" title="Balance of the credits available after this transaction."><span class="dashicons dashicons-editor-help"></span></a>
2324 <p>' . esc_html($row['fraudlabspro_credits']) . ' [<a href="https://www.fraudlabspro.com/pricing" target="_blank">Upgrade</a>]</p>
2325 </td>
2326 </tr>
2327 <tr>
2328 <td>
2329 <b>Transaction ID</b> <a href="javascript:;" class="flp-helper" title="Unique identifier for a transaction screened by FraudLabs Pro system."><span class="dashicons dashicons-editor-help"></span></a>
2330 <p><a href="https://www.fraudlabspro.com/merchant/transaction-details/' . esc_html($row['fraudlabspro_id']) . '" target="_blank">' . esc_html($row['fraudlabspro_id']) . '</a></p>
2331 </td>
2332 <td>
2333 <b>Triggered Rules</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro Rules triggered."><span class="dashicons dashicons-editor-help"></span></a>
2334 <p>' . ( strpos( $plan_name, 'Micro' ) ? '<span style="color:orange">Available for <a href="https://www.fraudlabspro.com/pricing" target="_blank">Mini plan</a> onward. Please <a href="https://www.fraudlabspro.com/merchant/login" target="_blank">upgrade</a>.</span>' : ( ( isset( $row['fraudlabspro_rules'] ) ) ? esc_html($row['fraudlabspro_rules']) : '-' ) ) . '</p>
2335 </td>
2336 </tr>
2337 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2338 <tr>
2339 <td><p style="font-size:16px;margin:0 auto;"><b>IP Geolocation</b></p></td>
2340 </tr>
2341 <tr>
2342 <td style="width:33%;">
2343 <b>IP Address</b>
2344 <p>' . esc_html($row['ip_address']) . '</p>
2345 </td>
2346 <td style="width:33%;">
2347 <b>Coordinate</b>
2348 <p>' . esc_html($row['ip_latitude']) . ', ' . esc_html($row['ip_longitude']) . '</p>
2349 </td>
2350 <td>
2351 <b>IP Location</b>
2352 <p>' . implode( ', ', $location ) . ' <a href="https://www.geolocation.com/' . esc_html($row['ip_address']) . '" target="_blank">[Map]</a></p>
2353 </td>
2354 </tr>
2355 <tr>
2356 <td>
2357 <b>Time Zone</b>
2358 <p>' . esc_html($row['ip_timezone']) . '</p>
2359 </td>
2360 <td>
2361 <b>IP to Billing Distance</b>
2362 <p>' . ( ( $row['distance_in_km'] ) ? ( esc_html($row['distance_in_km']) . ' KM / ' . esc_html($row['distance_in_mile']) . ' Miles' ) : '-' ) . '</p>
2363 </td>
2364 <td>
2365 <b>IP ISP Name</b> <a href="javascript:;" class="flp-helper" title="ISP of the IP address."><span class="dashicons dashicons-editor-help"></span></a>
2366 <p>' . esc_html($row['ip_isp_name']) . '</p>
2367 </td>
2368 </tr>
2369 <tr>
2370 <td>
2371 <b>IP Domain</b> <a href="javascript:;" class="flp-helper" title="Domain name of the IP address."><span class="dashicons dashicons-editor-help"></span></a>
2372 <p>' . esc_html($row['ip_domain']) . '</p>
2373 </td>
2374 <td>
2375 <b>IP Usage Type</b> <a href="javascript:;" class="flp-helper" title="Usage type of the IP address. E.g, ISP, Commercial, Residential."><span class="dashicons dashicons-editor-help"></span></a>
2376 <p>' . ( ($row['ip_usage_type'] == 'NA' ) ? 'Not available [<a href="https://www.fraudlabspro.com/pricing" target="_blank">Upgrade</a>]' : esc_html($row['ip_usage_type']) ) . '</p>
2377 </td>
2378 </tr>
2379 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2380 <tr>
2381 <td><p style="font-size:16px;margin:0 auto;"><b>Validation Information</b></p></td>
2382 </tr>
2383 <tr>
2384 <td>
2385 <b>Free Email Domain</b>
2386 <p>' . $this->parse_fraud_result( $row['is_free_email'] ) . '</p>
2387 </td>
2388 <td>
2389 <b>IP in Blacklist</b>
2390 <p>' . $this->parse_fraud_result( $row['is_ip_blacklist'] ) . '</p>
2391 </td>
2392 <td>
2393 <b>Email in Blacklist</b>
2394 <p>' . $this->parse_fraud_result( $row['is_email_blacklist'] ) . '</p>
2395 </td>
2396 </tr>
2397 <tr>
2398 <td>
2399 <b>Proxy IP</b> <a href="javascript:;" class="flp-helper" title="Whether IP address is from Anonymous Proxy Server."><span class="dashicons dashicons-editor-help"></span></a>
2400 <p>' . $this->parse_fraud_result( $row['is_proxy_ip_address'] ) . '</p>
2401 </td>
2402 <td>
2403 <b>Ship Forwarder</b> <a href="javascript:;" class="flp-helper" title="Whether shipping address is a freight forwarder address."><span class="dashicons dashicons-editor-help"></span></a>
2404 <p>' . $this->parse_fraud_result( $row['is_address_ship_forward'] ) . '</p>
2405 </td>
2406 <td>
2407 <b>Phone Verified</b>
2408 <p>'. ( isset( $row['is_phone_verified'] ) ? ( ( is_plugin_active( 'fraudlabs-pro-sms-verification/fraudlabspro-sms-verification.php' ) ) ? esc_html($row['is_phone_verified']) : '- [<a href="https://wordpress.org/plugins/fraudlabs-pro-sms-verification/" target="_blank">FraudLabs Pro SMS Verification Plugin Required</a>]' ) : 'NA [<a href="https://wordpress.org/plugins/fraudlabs-pro-sms-verification/" target="_blank">FraudLabs Pro SMS Verification Plugin Required</a>]' ) .'</p>
2409 </td>
2410 </tr>
2411 <tr>
2412 <td>
2413 <b>Disposable Email</b>
2414 <p>' . $this->parse_fraud_result( $row['is_email_disposable'] ?? '-' ) . '</p>
2415 </td>
2416 <td>
2417 <b>Disposable Phone</b>
2418 <p>' . $this->parse_fraud_result( $row['is_phone_disposable'] ?? '-' ) . '</p>
2419 </td>
2420 </tr>
2421 <tr>
2422 <td colspan="3">
2423 <b>Error Message</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro error message description."><span class="dashicons dashicons-editor-help"></span></a>
2424 <p>' . ( ( $row['fraudlabspro_message'] ) ? esc_html($row['fraudlabspro_error_code']) . ':' . esc_html($row['fraudlabspro_message']) : '-' ) . '</p>
2425 </td>
2426 </tr>
2427 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2428 <tr>
2429 <td colspan="3">
2430 <p>Please login to <a href="https://www.fraudlabspro.com/merchant/transaction-details/' . esc_html($row['fraudlabspro_id']) . '" target="_blank">FraudLabs Pro Merchant Area</a> for more information about this order.</p>
2431 </td>
2432 </tr>
2433 </table>
2434 <form id="review-action" method="post">
2435 <p align="center">
2436 <input type="hidden" name="transactionId" value="' . esc_html($row['fraudlabspro_id']) . '" >
2437 <input type="hidden" name="orderId" value="' . esc_html($row['order_id']) . '" >
2438 <input type="hidden" id="new_status" name="new_status" value="" />
2439 <input type="hidden" id="feedback_note" name="feedback_note" value="" />
2440 ' . wp_nonce_field('review-action', '_wpnonce_review_flp');
2441
2442 if( $row['fraudlabspro_status'] == 'REVIEW' ) {
2443 $table .= '
2444 <input type="submit" name="approve-flp" id="approve-order" value="' . __( 'Approve', $this->namespace ) . '" style="padding:10px 5px; background:#45B6AF; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;" />
2445 <input type="submit" name="reject-flp" id="reject-order" value="' . __( 'Reject', $this->namespace ) . '" style="padding:10px 5px; background:#F3565D; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;" />';
2446 }
2447
2448 if ( !isset( $row['is_blacklisted'] ) ) {
2449 $table .= '
2450 <input type="button" name="reject-blacklist" id="reject-blacklist-order" value="' . __( 'Blacklist', $this->namespace ) . '" style="padding:10px 5px; background:#666; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;color:#fff" />';
2451 }
2452
2453 $table .= '
2454 </p>
2455 </form>';
2456
2457 $report_display = ( get_option('wc_settings_woocommerce-fraudlabs-pro_expand_report') != 'yes' ) ? 'style="display:none"' : '';
2458 echo '
2459 <script>
2460 jQuery(function(){
2461 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table" ' . $report_display . '><blockquote>' . preg_replace( '/[\n]*/is', '', str_replace( '\'', '\\\'', $table ) ) . '</blockquote></div></div></div>\');';
2462
2463 if ( get_option('wc_settings_woocommerce-fraudlabs-pro_expand_report') != 'yes' ) {
2464 echo '
2465 if (window.location.href.indexOf("flp-details") > -1) {
2466 jQuery("#flp-details-table").toggle("show");
2467 jQuery("#flp-details-span").toggleClass("dashicons-arrow-up dashicons-arrow-down");
2468 }';
2469 }
2470
2471 echo '
2472 jQuery("#flp-details").click(function(){
2473 jQuery("#flp-details-table").toggle("show");
2474 jQuery("#flp-details-span").toggleClass("dashicons-arrow-up dashicons-arrow-down");
2475 });
2476
2477 jQuery("#reject-blacklist-order").click(function(){
2478 var note = prompt("Please enter the reason(s) for blacklisting this order. (Optional)");
2479 if(note !== null){
2480 jQuery("#feedback_note").val(note);
2481 jQuery("#new_status").val("reject_blacklist");
2482 jQuery("#review-action").submit();
2483 }
2484 });
2485 });
2486 </script>';
2487 } else {
2488 echo '
2489 <script>
2490 jQuery(function(){
2491 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table"><blockquote>This order has not been screened by FraudLabs Pro.</blockquote></div></div></div>\');
2492 });
2493 </script>';
2494 }
2495 } else {
2496 if ( $row->fraudlabspro_id != '' ){
2497 $table = '
2498 <style type="text/css">
2499 .fraudlabspro {width:100%;}
2500 .fraudlabspro td{padding:10px 0; vertical-align:top}
2501 .flp-helper{text-decoration:none}
2502
2503 /* color: Approve - #45b6af, Reject - #f3565d, Review - #dfba49 */
2504 </style>
2505
2506 <table class="fraudlabspro">
2507 <tr>
2508 <td colspan="3" style="text-align:center; background-color:#ab1b1c; border:1px solid #ab1b1c; padding-top:10px; padding-bottom:10px;">
2509 <a href="https://www.fraudlabspro.com" target="_blank"><img src="'. plugins_url( '/assets/images/logo_200.png', WC_FLP_DIR ) .'" alt="FraudLabs Pro" /></a>
2510 </td>
2511 </tr>';
2512
2513 $location = array();
2514 if ( strlen( $row->ip_country ) == 2 ) {
2515 $location = array(
2516 $this->get_country_by_code( esc_html($row->ip_country) ),
2517 esc_html($row->ip_region),
2518 esc_html($row->ip_city)
2519 );
2520
2521 $location = array_unique( $location );
2522 }
2523
2524 switch( $row->fraudlabspro_status ) {
2525 case 'REVIEW':
2526 $fraudlabspro_status_display = "REVIEW";
2527 $color = 'dfba49';
2528 break;
2529
2530 case 'REJECT':
2531 $fraudlabspro_status_display = "REJECTED";
2532 $color = 'f3565d';
2533 break;
2534
2535 case 'APPROVE':
2536 $fraudlabspro_status_display = "APPROVED";
2537 $color = '45b6af';
2538 break;
2539 }
2540
2541 $table .= '
2542 <tr>
2543 <td><p style="font-size:16px;margin: 0 auto;"><b>General</b></p></td>
2544 </tr>
2545 <tr>
2546 <td rowspan="2">
2547 <b>FraudLabs Pro Score</b> <a href="javascript:;" class="flp-helper" title="Risk score, 0 (low risk) - 100 (high risk)."><span class="dashicons dashicons-editor-help"></span></a><br/>
2548 <img class="img-responsive" alt="" src="//cdn.fraudlabspro.com/assets/img/scores/meter-' . ( ( $row['fraudlabspro_score'] ) ? esc_html($row['fraudlabspro_score']) . '.png' : 'nofraudprotection.png' ) . '" style="width:160px;" />
2549 </td>
2550 <td>
2551 <b>FraudLabs Pro Status</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro status."><span class="dashicons dashicons-editor-help"></span></a>
2552 <span style="color:#' . $color . ';font-size:28px; display:block;">' . $fraudlabspro_status_display . '</span>
2553 </td>
2554 <td>
2555 <b>Credit Balance</b> <a href="javascript:;" class="flp-helper" title="Balance of the credits available after this transaction."><span class="dashicons dashicons-editor-help"></span></a>
2556 <p>' . esc_html($row['fraudlabspro_credits']) . ' [<a href="https://www.fraudlabspro.com/pricing" target="_blank">Upgrade</a>]</p>
2557 </td>
2558 </tr>
2559 <tr>
2560 <td>
2561 <b>Transaction ID</b> <a href="javascript:;" class="flp-helper" title="Unique identifier for a transaction screened by FraudLabs Pro system."><span class="dashicons dashicons-editor-help"></span></a>
2562 <p><a href="https://www.fraudlabspro.com/merchant/transaction-details/' . esc_html($row['fraudlabspro_id']) . '" target="_blank">' . esc_html($row['fraudlabspro_id']) . '</a></p>
2563 </td>
2564 <td>
2565 <b>Triggered Rules</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro Rules triggered."><span class="dashicons dashicons-editor-help"></span></a>
2566 <p>' . ( strpos( $plan_name, 'Micro' ) ? '<span style="color:orange">Available for <a href="https://www.fraudlabspro.com/pricing" target="_blank">Mini plan</a> onward. Please <a href="https://www.fraudlabspro.com/merchant/login" target="_blank">upgrade</a>.</span>' : ( ( isset( $row['fraudlabspro_rules'] ) ) ? esc_html($row['fraudlabspro_rules']) : '-' ) ) . '</p>
2567 </td>
2568 </tr>
2569 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2570 <tr>
2571 <td><p style="font-size:16px;margin:0 auto;"><b>IP Geolocation</b></p></td>
2572 </tr>
2573 <tr>
2574 <td style="width:33%;">
2575 <b>IP Address</b>
2576 <p>' . esc_html($row['ip_address']) . '</p>
2577 </td>
2578 <td style="width:33%;">
2579 <b>Coordinate</b>
2580 <p>' . esc_html($row['ip_latitude']) . ', ' . esc_html($row['ip_longitude']) . '</p>
2581 </td>
2582 <td>
2583 <b>IP Location</b>
2584 <p>' . implode( ', ', $location ) . ' <a href="https://www.geolocation.com/' . esc_html($row['ip_address']) . '" target="_blank">[Map]</a></p>
2585 </td>
2586 </tr>
2587 <tr>
2588 <td>
2589 <b>Time Zone</b>
2590 <p>' . esc_html($row['ip_timezone']) . '</p>
2591 </td>
2592 <td>
2593 <b>IP to Billing Distance</b>
2594 <p>' . ( ( $row['distance_in_km'] ) ? ( esc_html($row['distance_in_km']) . ' KM / ' . esc_html($row['distance_in_mile']) . ' Miles' ) : '-' ) . '</p>
2595 </td>
2596 <td>
2597 <b>IP ISP Name</b> <a href="javascript:;" class="flp-helper" title="ISP of the IP address."><span class="dashicons dashicons-editor-help"></span></a>
2598 <p>' . esc_html($row['ip_isp_name']) . '</p>
2599 </td>
2600 </tr>
2601 <tr>
2602 <td>
2603 <b>IP Domain</b> <a href="javascript:;" class="flp-helper" title="Domain name of the IP address."><span class="dashicons dashicons-editor-help"></span></a>
2604 <p>' . esc_html($row['ip_domain']) . '</p>
2605 </td>
2606 <td>
2607 <b>IP Usage Type</b> <a href="javascript:;" class="flp-helper" title="Usage type of the IP address. E.g, ISP, Commercial, Residential."><span class="dashicons dashicons-editor-help"></span></a>
2608 <p>' . ( ($row['ip_usage_type'] == 'NA' ) ? 'Not available [<a href="https://www.fraudlabspro.com/pricing" target="_blank">Upgrade</a>]' : esc_html($row['ip_usage_type']) ) . '</p>
2609 </td>
2610 </tr>
2611 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2612 <tr>
2613 <td><p style="font-size:16px;margin:0 auto;"><b>Validation Information</b></p></td>
2614 </tr>
2615 <tr>
2616 <td>
2617 <b>Free Email Domain</b>
2618 <p>' . $this->parse_fraud_result( $row['is_free_email'] ) . '</p>
2619 </td>
2620 <td>
2621 <b>IP in Blacklist</b>
2622 <p>' . $this->parse_fraud_result( $row['is_ip_blacklist'] ) . '</p>
2623 </td>
2624 <td>
2625 <b>Email in Blacklist</b>
2626 <p>' . $this->parse_fraud_result( $row['is_email_blacklist'] ) . '</p>
2627 </td>
2628 </tr>
2629 <tr>
2630 <td>
2631 <b>Proxy IP</b> <a href="javascript:;" class="flp-helper" title="Whether IP address is from Anonymous Proxy Server."><span class="dashicons dashicons-editor-help"></span></a>
2632 <p>' . $this->parse_fraud_result( $row['is_proxy_ip_address'] ) . '</p>
2633 </td>
2634 <td>
2635 <b>Ship Forwarder</b> <a href="javascript:;" class="flp-helper" title="Whether shipping address is a freight forwarder address."><span class="dashicons dashicons-editor-help"></span></a>
2636 <p>' . $this->parse_fraud_result( $row['is_address_ship_forward'] ) . '</p>
2637 </td>
2638 <td>
2639 <b>Phone Verified</b>
2640 <p>'. ( isset( $row['is_phone_verified'] ) ? ( ( is_plugin_active( 'fraudlabs-pro-sms-verification/fraudlabspro-sms-verification.php' ) ) ? esc_html($row['is_phone_verified']) : '- [<a href="https://wordpress.org/plugins/fraudlabs-pro-sms-verification/" target="_blank">FraudLabs Pro SMS Verification Plugin Required</a>]' ) : 'NA [<a href="https://wordpress.org/plugins/fraudlabs-pro-sms-verification/" target="_blank">FraudLabs Pro SMS Verification Plugin Required</a>]' ) .'</p>
2641 </td>
2642 </tr>
2643 <tr>
2644 <td colspan="3">
2645 <b>Error Message</b> <a href="javascript:;" class="flp-helper" title="FraudLabs Pro error message description."><span class="dashicons dashicons-editor-help"></span></a>
2646 <p>' . ( ( $row['fraudlabspro_message'] ) ? esc_html($row['fraudlabspro_error_code']) . ':' . esc_html($row['fraudlabspro_message']) : '-' ) . '</p>
2647 </td>
2648 </tr>
2649 <tr><td colspan="3" style="margin:10px auto;"><hr></td></tr>
2650 <tr>
2651 <td colspan="3">
2652 <p>Please login to <a href="https://www.fraudlabspro.com/merchant/transaction-details/' . esc_html($row['fraudlabspro_id']) . '" target="_blank">FraudLabs Pro Merchant Area</a> for more information about this order.</p>
2653 </td>
2654 </tr>
2655 </table>
2656 <form id="review-action" method="post">
2657 <p align="center">
2658 <input type="hidden" name="transactionId" value="' . esc_html($row->fraudlabspro_id) . '" >
2659 <input type="hidden" name="orderId" value="' . esc_html($row->order_id) . '" >
2660 <input type="hidden" id="new_status" name="new_status" value="" />
2661 <input type="hidden" id="feedback_note" name="feedback_note" value="" />
2662 ' . wp_nonce_field('review-action', '_wpnonce_review_flp');
2663
2664 if( $row->fraudlabspro_status == 'REVIEW' ) {
2665 $table .= '
2666 <input type="submit" name="approve-flp" id="approve-order" value="' . __( 'Approve', $this->namespace ) . '" style="padding:10px 5px; background:#45B6AF; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;" />
2667 <input type="submit" name="reject-flp" id="reject-order" value="' . __( 'Reject', $this->namespace ) . '" style="padding:10px 5px; background:#F3565D; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;" />';
2668 }
2669
2670 if ( !isset( $row->is_blacklisted ) ) {
2671 $table .= '
2672 <input type="button" name="reject-blacklist" id="reject-blacklist-order" value="' . __( 'Blacklist', $this->namespace ) . '" style="padding:10px 5px; background:#666; color:#fff; border:1px solid #ccc; min-width:100px; cursor: pointer;color:#fff" />';
2673 }
2674
2675 $table .= '
2676 </p>
2677 </form>';
2678
2679 $report_display = ( get_option('wc_settings_woocommerce-fraudlabs-pro_expand_report') != 'yes' ) ? 'style="display:none"' : '';
2680 echo '
2681 <script>
2682 jQuery(function(){
2683 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table" ' . $report_display . '><blockquote>' . preg_replace( '/[\n]*/is', '', str_replace( '\'', '\\\'', $table ) ) . '</blockquote></div></div></div>\');
2684
2685 jQuery("#flp-details").click(function(){
2686 jQuery("#flp-details-table").toggle("show");
2687 jQuery("#flp-details-span").toggleClass("dashicons-arrow-up dashicons-arrow-down");
2688 });
2689
2690 jQuery("#reject-blacklist-order").click(function(){
2691 var note = prompt("Please enter the reason(s) for blacklisting this order. (Optional)");
2692 if(note !== null){
2693 jQuery("#feedback_note").val(note);
2694 jQuery("#new_status").val("reject_blacklist");
2695 jQuery("#review-action").submit();
2696 }
2697 });
2698 });
2699 </script>';
2700 } else {
2701 echo '
2702 <script>
2703 jQuery(function(){
2704 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table"><blockquote>This order has not been screened by FraudLabs Pro.</blockquote></div></div></div>\');
2705 });
2706 </script>';
2707 }
2708 }
2709 } else {
2710 echo '
2711 <script>
2712 jQuery(function(){
2713 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table"><blockquote>This order has not been screened by FraudLabs Pro.</blockquote></div></div></div>\');
2714 });
2715 </script>';
2716 }
2717 } else {
2718 echo '
2719 <script>
2720 jQuery(function(){
2721 jQuery("#woocommerce-order-items").before(\'<div class="metabox-holder"><div class="postbox" style="padding: 10px 0px;"><div id="flp-details"><h2 style="text-align:center; display:inline;">FraudLabs Pro Details</h2> <a href="javascript:;" class="flp-helper" title="Collapse/Expand"><span style="float:right; padding-right:10px;" class="dashicons dashicons-arrow-up" id="flp-details-span"></span></a></div><div id="flp-details-table"><blockquote>This order has not been screened by FraudLabs Pro.</blockquote></div></div></div>\');
2722 });
2723 </script>';
2724 }
2725 }
2726
2727
2728 /**
2729 * Auto approve the order as the merchant mark the order as completed.
2730 */
2731 public function order_status_completed( $order_id ) {
2732 if ( get_option('wc_settings_woocommerce-fraudlabs-pro_change_status_auto') != 'yes' ) {
2733 return;
2734 }
2735
2736 $result = get_post_meta( $order_id, '_fraudlabspro' );
2737
2738 if (!$result) {
2739 $table_name = $this->create_flpwc_table();
2740 $result = $this->get_flpwc_data($table_name, $order_id, '_fraudlabspro');
2741 }
2742
2743 $idx = count( $result ) - 1;
2744
2745 if ($idx < 0) {
2746 return;
2747 }
2748
2749 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2750 $row = json_decode( $result[$idx] );
2751 } else {
2752 $row = $result[$idx];
2753 }
2754
2755 $flp_id = is_array( $result[$idx] ) ? $row['fraudlabspro_id'] : $row->fraudlabspro_id;
2756 $queries = [
2757 'key' => $this->api_key,
2758 'action' => 'APPROVE',
2759 'id' => $flp_id,
2760 'format' => 'json',
2761 'source' => 'woocommerce',
2762 'triggered_by' => 'order_status_completed'
2763 ];
2764 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/feedback', $queries );
2765
2766 if ( $request ) {
2767 $response = json_decode( $request );
2768
2769 if ( is_object( $response ) ) {
2770 if ( is_array( $result[$idx] ) ) {
2771 $row['fraudlabspro_status'] = 'APPROVE';
2772 } else {
2773 if (isset($row->fraudlabspro_status)) {
2774 $row->fraudlabspro_status = 'APPROVE';
2775 }
2776 }
2777 update_post_meta( $order_id, '_fraudlabspro', $row );
2778 $table_name = $this->create_flpwc_table();
2779 $this->update_flpwc_data($table_name, $order_id, '_fraudlabspro', $row);
2780 }
2781 }
2782 }
2783
2784
2785 /**
2786 * Auto reject the order as the merchant mark the order as cancelled.
2787 */
2788 public function order_status_cancelled( $order_id ) {
2789 if ( get_option('wc_settings_woocommerce-fraudlabs-pro_change_status_auto') != 'yes' ) {
2790 return;
2791 }
2792
2793 $result = get_post_meta( $order_id, '_fraudlabspro' );
2794
2795 if (!$result) {
2796 $table_name = $this->create_flpwc_table();
2797 $result = $this->get_flpwc_data($table_name, $order_id, '_fraudlabspro');
2798 }
2799
2800 $idx = count( $result ) - 1;
2801
2802 if ($idx < 0) {
2803 return;
2804 }
2805
2806 if ( !is_array( $result[$idx] ) && !is_object( $result[$idx] ) ) {
2807 $row = json_decode( $result[$idx] );
2808 } else {
2809 $row = $result[$idx];
2810 }
2811
2812 // Configures FraudLabs Pro API key
2813 $flp_id = is_array( $result[$idx] ) ? $row['fraudlabspro_id'] : $row->fraudlabspro_id;
2814 $queries = [
2815 'key' => $this->api_key,
2816 'action' => 'REJECT',
2817 'id' => $flp_id,
2818 'format' => 'json',
2819 'source' => 'woocommerce',
2820 'triggered_by' => 'order_status_cancelled'
2821 ];
2822 $request = $this->post( 'https://api.fraudlabspro.com/v2/order/feedback', $queries );
2823
2824 if ( $request ) {
2825 $response = json_decode( $request );
2826
2827 if ( is_object( $response ) ) {
2828 if ( is_array( $result[$idx] ) ) {
2829 $row['fraudlabspro_status'] = 'REJECT';
2830 } else {
2831 if (isset($row->fraudlabspro_status)) {
2832 $row->fraudlabspro_status = 'REJECT';
2833 }
2834 }
2835 update_post_meta( $order_id, '_fraudlabspro', $row );
2836 $table_name = $this->create_flpwc_table();
2837 $this->update_flpwc_data($table_name, $order_id, '_fraudlabspro', $row);
2838 }
2839 }
2840 }
2841
2842
2843 public function pre_payment_complete( $order_id ) {
2844 $this->write_debug_log( 'Prepayment completed for Order ' . $order_id . '.');
2845 }
2846
2847
2848 public function payment_complete( $order_id ) {
2849 $this->write_debug_log( 'Payment completed for Order ' . $order_id . '.');
2850 }
2851
2852
2853 public function validate_api_key() {
2854 check_ajax_referer('validate-api-key', '__nonce');
2855
2856 try {
2857 $apiKey = ( isset( $_POST['token'] ) ) ? sanitize_text_field($_POST['token']) : '';
2858
2859 $request = wp_remote_get( 'https://api.fraudlabspro.com/v2/plan/result?' . http_build_query( array(
2860 'key' => $apiKey,
2861 'format' => 'json',
2862 'store' => $_SERVER['HTTP_HOST'] ?? '',
2863 'src' => 'WooCommerce',
2864 ) ) );
2865
2866 if ( ! is_wp_error( $request ) ) {
2867 // Get the HTTP response
2868 $response = json_decode( wp_remote_retrieve_body( $request ) );
2869
2870 if ( is_object( $response ) ) {
2871 if ( $response->plan_name == '') {
2872 die('Invalid API Key.');
2873 }
2874
2875 update_option( 'wc_settings_woocommerce-fraudlabs-pro_enabled', 'yes' );
2876 update_option( 'wc_settings_woocommerce-fraudlabs-pro_api_key', $apiKey );
2877
2878 die( 'SUCCESS_' . esc_html($response->plan_name) );
2879 } else {
2880 die( 'Response Error.' );
2881 }
2882 } else {
2883 die( 'WP Error.' );
2884 }
2885 } catch (Exception $e) {
2886 die( $e->getMessage() );
2887 }
2888 }
2889
2890
2891 /**
2892 * Write to debug log to record details of process.
2893 */
2894 public function write_debug_log( $message ) {
2895 if ( get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log') != 'yes' ) {
2896 return;
2897 }
2898
2899 if ( get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') != '' ) {
2900 $path = ABSPATH . get_option('wc_settings_woocommerce-fraudlabs-pro_debug_log_path') . 'debug.log';
2901 } else {
2902 $path = FRAUDLABS_PRO_ROOT . 'debug.log';
2903 }
2904
2905 if ( is_array( $message ) || is_object( $message ) ) {
2906 file_put_contents( $path, gmdate('Y-m-d H:i:s') . "\t" . print_r( $message, true ) . "\n", FILE_APPEND );
2907 } else {
2908 file_put_contents( $path, gmdate('Y-m-d H:i:s') . "\t" . $message . "\n", FILE_APPEND );
2909 }
2910 }
2911
2912
2913 public function submit_feedback() {
2914 check_ajax_referer('submit-feedback', '__nonce');
2915
2916 $feedback = ( isset( $_POST['feedback'] ) ) ? sanitize_text_field($_POST['feedback']) : '';
2917 $others = ( isset($_POST['others'] ) ) ? sanitize_text_field($_POST['others']) : '';
2918
2919 $options = [
2920 1 => 'I no longer need the plugin',
2921 2 => 'I couldn\'t get the plugin to work',
2922 3 => 'The plugin doesn\'t meet my requirements',
2923 4 => 'Other concerns' . (($others) ? (' - ' . $others) : ''),
2924 ];
2925
2926 if ( isset($options[$feedback] ) ) {
2927 if ( !class_exists('WP_Http') ) {
2928 include_once ABSPATH . WPINC . '/class-http.php';
2929 }
2930
2931 $request = new WP_Http();
2932 $response = $request->request('https://www.fraudlabspro.com/wp-plugin-feedback?' . http_build_query([
2933 'name' => 'fraudlabs-pro-for-woocommerce',
2934 'message' => $options[$feedback],
2935 ]), ['timeout' => 5]);
2936 }
2937 }
2938
2939
2940 public function admin_footer_text($footer_text) {
2941 $plugin_name = 'fraudlabs-pro-for-woocommerce';
2942 $current_screen = get_current_screen();
2943
2944 if (($current_screen && strpos($current_screen->id, 'woocommerce-fraudlabs-pro') !== false)) {
2945 $footer_text .= sprintf(
2946 __('</br>Enjoyed %1$s? Please leave us a %2$s rating. A huge thanks in advance!', $plugin_name),
2947 '<strong>' . __('FraudLabs Pro for WooCommerce', $plugin_name) . '</strong>',
2948 '<a href="https://wordpress.org/support/plugin/' . $plugin_name . '/reviews/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
2949 );
2950 }
2951
2952 if ($current_screen->id == 'plugins') {
2953 return $footer_text . '
2954 <div id="fraudlabs-pro-for-woocommerce-feedback-modal" class="hidden" style="max-width:800px">
2955 <span id="fraudlabs-pro-for-woocommerce-feedback-response"></span>
2956 <p>
2957 <strong>Would you mind sharing with us the reason to deactivate the plugin?</strong>
2958 </p>
2959 <p>
2960 <label>
2961 <input type="radio" name="fraudlabs-pro-for-woocommerce-feedback" value="1"> I no longer need the plugin
2962 </label>
2963 </p>
2964 <p>
2965 <label>
2966 <input type="radio" name="fraudlabs-pro-for-woocommerce-feedback" value="2"> I couldn\'t get the plugin to work
2967 </label>
2968 </p>
2969 <p>
2970 <label>
2971 <input type="radio" name="fraudlabs-pro-for-woocommerce-feedback" value="3"> The plugin doesn\'t meet my requirements
2972 </label>
2973 </p>
2974 <p>
2975 <label>
2976 <input type="radio" name="fraudlabs-pro-for-woocommerce-feedback" value="4"> Other concerns
2977 <br><br>
2978 <textarea id="fraudlabs-pro-for-woocommerce-feedback-other" style="display:none;width:100%"></textarea>
2979 </label>
2980 </p>
2981 <p>
2982 <div style="float:left">
2983 <input type="button" id="fraudlabs-pro-for-woocommerce-submit-feedback-button" class="button button-danger" value="Submit & Deactivate" />
2984 </div>
2985 <div style="float:right">
2986 <a href="#">Skip & Deactivate</a>
2987 </div>
2988 </p>
2989 <input type="hidden" id="fraudlabs_pro_woocommerce_feedback_nonce" value="' . wp_create_nonce('submit-feedback') . '">
2990 </div>';
2991 }
2992
2993 return $footer_text;
2994 }
2995
2996
2997 /**
2998 * Use WP_LOADED for the callback function to work.
2999 */
3000 function wc_flp_callback() {
3001 global $wp;
3002
3003 if ( get_option( 'wc_settings_woocommerce-fraudlabs-pro_api_key' ) == '' ) {
3004 update_option( 'wc_settings_woocommerce-fraudlabs-pro_approve_status', 'wc-processing' );
3005 update_option( 'wc_settings_woocommerce-fraudlabs-pro_review_status', 'wc-on-hold' );
3006 update_option( 'wc_settings_woocommerce-fraudlabs-pro_reject_status', 'wc-cancelled' );
3007 update_option( 'wc_settings_woocommerce-fraudlabs-pro_reject_failed_order', 'yes' );
3008 update_option( 'wc_settings_woocommerce-fraudlabs-pro_expand_report', 'yes' );
3009 flush_rewrite_rules();
3010 }
3011
3012 if ( get_option( 'wc_settings_woocommerce-fraudlabs-pro_reject_failed_order' ) == '' ) {
3013 update_option( 'wc_settings_woocommerce-fraudlabs-pro_reject_failed_order', 'yes' );
3014 }
3015
3016 $current_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
3017 $current_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
3018 $current_url = $current_host . $current_uri;
3019
3020 if (strpos($current_url, 'flp-callback')) {
3021 include(plugin_dir_path(__FILE__) . '/flp-callback.php');
3022 }
3023 }
3024
3025
3026 /**
3027 * Parse FraudLabs Pro API result.
3028 */
3029 private function parse_fraud_result( $result ) {
3030 if ( $result == 'Y' )
3031 return 'Yes';
3032
3033 if ( $result == 'N' )
3034 return 'No';
3035
3036 if ( $result == 'NA' )
3037 return '-';
3038
3039 return $result;
3040 }
3041
3042 /**
3043 * Get country name by country code.
3044 */
3045 private function get_country_by_code( $code ) {
3046 $countries = array( 'AF' => 'Afghanistan','AL' => 'Albania','DZ' => 'Algeria','AS' => 'American Samoa','AD' => 'Andorra','AO' => 'Angola','AI' => 'Anguilla','AQ' => 'Antarctica','AG' => 'Antigua and Barbuda','AR' => 'Argentina','AM' => 'Armenia','AW' => 'Aruba','AU' => 'Australia','AT' => 'Austria','AZ' => 'Azerbaijan','BS' => 'Bahamas','BH' => 'Bahrain','BD' => 'Bangladesh','BB' => 'Barbados','BY' => 'Belarus','BE' => 'Belgium','BZ' => 'Belize','BJ' => 'Benin','BM' => 'Bermuda','BT' => 'Bhutan','BO' => 'Bolivia','BA' => 'Bosnia and Herzegovina','BW' => 'Botswana','BV' => 'Bouvet Island','BR' => 'Brazil','IO' => 'British Indian Ocean Territory','BN' => 'Brunei Darussalam','BG' => 'Bulgaria','BF' => 'Burkina Faso','BI' => 'Burundi','KH' => 'Cambodia','CM' => 'Cameroon','CA' => 'Canada','CV' => 'Cape Verde','KY' => 'Cayman Islands','CF' => 'Central African Republic','TD' => 'Chad','CL' => 'Chile','CN' => 'China','CX' => 'Christmas Island','CC' => 'Cocos (Keeling) Islands','CO' => 'Colombia','KM' => 'Comoros','CG' => 'Congo','CK' => 'Cook Islands','CR' => 'Costa Rica','CI' => 'Cote D\'Ivoire','HR' => 'Croatia','CU' => 'Cuba','CY' => 'Cyprus','CZ' => 'Czech Republic','CD' => 'Democratic Republic of Congo','DK' => 'Denmark','DJ' => 'Djibouti','DM' => 'Dominica','DO' => 'Dominican Republic','TP' => 'East Timor','EC' => 'Ecuador','EG' => 'Egypt','SV' => 'El Salvador','GQ' => 'Equatorial Guinea','ER' => 'Eritrea','EE' => 'Estonia','ET' => 'Ethiopia','FK' => 'Falkland Islands (Malvinas)','FO' => 'Faroe Islands','FJ' => 'Fiji','FI' => 'Finland','FR' => 'France','FX' => 'France, Metropolitan','GF' => 'French Guiana','PF' => 'French Polynesia','TF' => 'French Southern Territories','GA' => 'Gabon','GM' => 'Gambia','GE' => 'Georgia','DE' => 'Germany','GH' => 'Ghana','GI' => 'Gibraltar','GR' => 'Greece','GL' => 'Greenland','GD' => 'Grenada','GP' => 'Guadeloupe','GU' => 'Guam','GT' => 'Guatemala','GN' => 'Guinea','GW' => 'Guinea-bissau','GY' => 'Guyana','HT' => 'Haiti','HM' => 'Heard and Mc Donald Islands','HN' => 'Honduras','HK' => 'Hong Kong','HU' => 'Hungary','IS' => 'Iceland','IN' => 'India','ID' => 'Indonesia','IR' => 'Iran (Islamic Republic of)','IQ' => 'Iraq','IE' => 'Ireland','IL' => 'Israel','IT' => 'Italy','JM' => 'Jamaica','JP' => 'Japan','JO' => 'Jordan','KZ' => 'Kazakhstan','KE' => 'Kenya','KI' => 'Kiribati','KR' => 'Korea, Republic of','KW' => 'Kuwait','KG' => 'Kyrgyzstan','LA' => 'Lao People\'s Democratic Republic','LV' => 'Latvia','LB' => 'Lebanon','LS' => 'Lesotho','LR' => 'Liberia','LY' => 'Libyan Arab Jamahiriya','LI' => 'Liechtenstein','LT' => 'Lithuania','LU' => 'Luxembourg','MO' => 'Macau','MK' => 'Macedonia','MG' => 'Madagascar','MW' => 'Malawi','MY' => 'Malaysia','MV' => 'Maldives','ML' => 'Mali','MT' => 'Malta','MH' => 'Marshall Islands','MQ' => 'Martinique','MR' => 'Mauritania','MU' => 'Mauritius','YT' => 'Mayotte','MX' => 'Mexico','FM' => 'Micronesia, Federated States of','MD' => 'Moldova, Republic of','MC' => 'Monaco','MN' => 'Mongolia','MS' => 'Montserrat','MA' => 'Morocco','MZ' => 'Mozambique','MM' => 'Myanmar','NA' => 'Namibia','NR' => 'Nauru','NP' => 'Nepal','NL' => 'Netherlands','AN' => 'Netherlands Antilles','NC' => 'New Caledonia','NZ' => 'New Zealand','NI' => 'Nicaragua','NE' => 'Niger','NG' => 'Nigeria','NU' => 'Niue','NF' => 'Norfolk Island','KP' => 'North Korea','MP' => 'Northern Mariana Islands','NO' => 'Norway','OM' => 'Oman','PK' => 'Pakistan','PW' => 'Palau','PA' => 'Panama','PG' => 'Papua New Guinea','PY' => 'Paraguay','PE' => 'Peru','PH' => 'Philippines','PN' => 'Pitcairn','PL' => 'Poland','PT' => 'Portugal','PR' => 'Puerto Rico','QA' => 'Qatar','RE' => 'Reunion','RO' => 'Romania','RU' => 'Russian Federation','RW' => 'Rwanda','KN' => 'Saint Kitts and Nevis','LC' => 'Saint Lucia','VC' => 'Saint Vincent and the Grenadines','WS' => 'Samoa','SM' => 'San Marino','ST' => 'Sao Tome and Principe','SA' => 'Saudi Arabia','SN' => 'Senegal','SC' => 'Seychelles','SL' => 'Sierra Leone','SG' => 'Singapore','SK' => 'Slovak Republic','SI' => 'Slovenia','SB' => 'Solomon Islands','SO' => 'Somalia','ZA' => 'South Africa','GS' => 'South Georgia And The South Sandwich Islands','ES' => 'Spain','LK' => 'Sri Lanka','SH' => 'St. Helena','PM' => 'St. Pierre and Miquelon','SD' => 'Sudan','SR' => 'Suriname','SJ' => 'Svalbard and Jan Mayen Islands','SZ' => 'Swaziland','SE' => 'Sweden','CH' => 'Switzerland','SY' => 'Syrian Arab Republic','TW' => 'Taiwan','TJ' => 'Tajikistan','TZ' => 'Tanzania, United Republic of','TH' => 'Thailand','TG' => 'Togo','TK' => 'Tokelau','TO' => 'Tonga','TT' => 'Trinidad and Tobago','TN' => 'Tunisia','TR' => 'Turkey','TM' => 'Turkmenistan','TC' => 'Turks and Caicos Islands','TV' => 'Tuvalu','UG' => 'Uganda','UA' => 'Ukraine','AE' => 'United Arab Emirates','GB' => 'United Kingdom','US' => 'United States','UM' => 'United States Minor Outlying Islands','UY' => 'Uruguay','UZ' => 'Uzbekistan','VU' => 'Vanuatu','VA' => 'Vatican City State (Holy See)','VE' => 'Venezuela','VN' => 'Viet Nam','VG' => 'Virgin Islands (British)','VI' => 'Virgin Islands (U.S.)','WF' => 'Wallis and Futuna Islands','EH' => 'Western Sahara','YE' => 'Yemen','YU' => 'Yugoslavia','ZM' => 'Zambia','ZW' => 'Zimbabwe' );
3047
3048 return ( isset( $countries[$code] ) ) ? $countries[$code] : NULL;
3049 }
3050
3051 /**
3052 * Get plugin settings.
3053 */
3054 private function get_setting( $key ) {
3055 return get_option( 'wc_settings_woocommerce-fraudlabs-pro_' . $key );
3056 }
3057
3058 /**
3059 * Update plugin settings.
3060 */
3061 private function update_setting( $key, $value = null ) {
3062 return update_option( 'wc_settings_woocommerce-fraudlabs-pro_' . $key, $value );
3063 }
3064
3065 /**
3066 * Hash a string to send to FraudLabs Pro API.
3067 */
3068 private function hash_string( $s ) {
3069 $hash = 'fraudlabspro_' . $s;
3070
3071 for( $i = 0; $i < 65536; $i++ ) {
3072 $hash = sha1( 'fraudlabspro_' . $hash );
3073 }
3074
3075 $hash2 = hash('sha256', $hash);
3076
3077 return $hash2;
3078 }
3079
3080 private function create_flpwc_table() {
3081 global $wpdb;
3082 $charset_collate = $wpdb->get_charset_collate();
3083 $table_name = $wpdb->prefix . 'fraudlabspro_wc';
3084
3085 $sql = "CREATE TABLE $table_name (
3086 `flp_wc_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
3087 `post_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
3088 `meta_key` VARCHAR(255) NULL DEFAULT NULL,
3089 `meta_value` LONGTEXT NULL DEFAULT NULL,
3090 PRIMARY KEY (`flp_wc_id`) USING BTREE,
3091 INDEX `post_id` (`post_id`) USING BTREE,
3092 INDEX `meta_key` (`meta_key`) USING BTREE
3093 ) $charset_collate;";
3094
3095 $sql1 = $wpdb->prepare("SHOW TABLES LIKE %s", $table_name);
3096 $tbExists = $wpdb->get_row($sql1);
3097
3098 if (!$tbExists) {
3099 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
3100 dbDelta($sql);
3101 }
3102
3103 return $table_name;
3104 }
3105
3106 private function add_flpwc_data($table_name, $post_id, $key, $value) {
3107 global $wpdb;
3108
3109 $meta_subtype = get_object_subtype( 'post', $post_id );
3110 $key = wp_unslash( $key );
3111 $value = wp_unslash( $value );
3112 $value = sanitize_meta( $key, $value, 'post', $meta_subtype );
3113 $value = maybe_serialize( $value );
3114
3115 return $wpdb->replace($table_name, array('post_id' => $post_id, 'meta_key' => $key, 'meta_value' => $value), array('%s', '%s', '%s'));
3116 }
3117
3118 private function get_flpwc_data($table_name, $post_id, $key) {
3119 global $wpdb;
3120
3121 $data = [];
3122 $sql = $wpdb->prepare("SELECT `meta_value` FROM $table_name WHERE post_id = %s AND meta_key = %s LIMIT 1", $post_id, $key);
3123 $metaValue = $wpdb->get_row($sql);
3124
3125 if ($metaValue) {
3126 $data[] = unserialize($metaValue->meta_value);
3127 }
3128 return $data;
3129 }
3130
3131 private function update_flpwc_data($table_name, $post_id, $key, $value) {
3132 global $wpdb;
3133
3134 $meta_subtype = get_object_subtype( 'post', $post_id );
3135 $key = wp_unslash( $key );
3136 $value = wp_unslash( $value );
3137 $value = sanitize_meta( $key, $value, 'post', $meta_subtype );
3138 $value = maybe_serialize( $value );
3139
3140 return $wpdb->update($table_name, array('meta_value' => $value), array('post_id' => $post_id, 'meta_key' => $key), array('%s'), array('%s', '%s'));
3141 }
3142
3143 /**
3144 * Validate a credit card number.
3145 */
3146 private function is_credit_card( $number ) {
3147 $card_type = null;
3148
3149 $patterns = array(
3150 '/^4\d{12}(\d\d\d){0,1}$/' => 'visa',
3151 '/^(5[12345]|2[234567])\d{14}$/' => 'mastercard',
3152 '/^3[47]\d{13}$/' => 'amex',
3153 '/^6011\d{12}$/' => 'discover',
3154 '/^30[012345]\d{11}$/' => 'diners',
3155 '/^3[68]\d{12}$/' => 'diners'
3156 );
3157
3158 foreach ( $patterns as $regex => $type ) {
3159 if ( @preg_match( $regex, (string)$number ) ) {
3160 $card_type = $type;
3161 break;
3162 }
3163 }
3164
3165 if ( !$card_type ) {
3166 return false;
3167 }
3168
3169 $rev_code = strrev( $number );
3170 $checksum = 0;
3171
3172 for ( $i = 0; $i < strlen( $rev_code ); $i++ ) {
3173 $current = intval ( $rev_code[$i] );
3174
3175 if ( $i & 1 ) {
3176 $current *= 2;
3177 }
3178
3179 $checksum += $current % 10;
3180
3181 if ( $current > 9 ) {
3182 $checksum += 1;
3183 }
3184 }
3185
3186 return ( $checksum % 10 == 0 ) ? true : false;
3187 }
3188
3189 /**
3190 * Get order notes details.
3191 */
3192 private function get_order_notes( $order_id ) {
3193 global $wpdb;
3194
3195 $table_perfixed = $wpdb->prefix . 'comments';
3196 $results = $wpdb->get_results("
3197 SELECT * FROM $table_perfixed
3198 WHERE `comment_post_ID` = $order_id
3199 AND `comment_type` LIKE 'order_note'
3200 AND `comment_content` LIKE 'FraudLabs Pro Status:%'
3201 ");
3202
3203 if ( count( $results ) > 0 ) {
3204 foreach ( $results as $note ) {
3205 $order_note[] = array(
3206 'note_id' => $note->comment_ID,
3207 'note_date' => $note->comment_date,
3208 'note_author' => $note->comment_author,
3209 'note_content' => $note->comment_content,
3210 );
3211 }
3212 return $order_note;
3213 } else {
3214 return false;
3215 }
3216 }
3217
3218 private function create_custom_nonce($action) {
3219 $nonce = wp_create_nonce($action);
3220 $nonceExpiry = $nonce . '|' . (time() + 86400);
3221 return $nonceExpiry;
3222 }
3223
3224 private function post($url, $fields = '') {
3225 $ch = curl_init();
3226 curl_setopt($ch, CURLOPT_URL, $url);
3227 curl_setopt($ch, CURLOPT_FAILONERROR, false);
3228 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
3229 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
3230 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
3231 curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
3232 curl_setopt($ch, CURLOPT_HTTP_VERSION, '1.1');
3233 curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
3234 curl_setopt($ch, CURLOPT_TIMEOUT, 60);
3235
3236 if (!empty($fields)) {
3237 curl_setopt($ch, CURLOPT_POST, 1);
3238 curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($fields)) ? http_build_query($fields) : $fields);
3239 }
3240
3241 $response = curl_exec($ch);
3242 $info = curl_getinfo($ch);
3243
3244 if (!curl_errno($ch)) {
3245 return $response;
3246 } else {
3247 $this->write_debug_log($info);
3248 $this->write_debug_log('CURL Error: ' . $url . ' - ' . curl_error($ch));
3249 return 'CURL Error: ' . curl_error($ch);
3250 }
3251 }
3252
3253 private function http($url, $fields = '') {
3254 $ch = curl_init();
3255
3256 if ($fields) {
3257 $data_string = json_encode($fields);
3258 curl_setopt($ch, CURLOPT_POST, 1);
3259 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
3260 }
3261
3262 curl_setopt($ch, CURLOPT_URL, $url);
3263 curl_setopt($ch, CURLOPT_FAILONERROR, 1);
3264 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
3265 curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
3266 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
3267 curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
3268 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
3269 curl_setopt($ch, CURLOPT_HTTP_VERSION, '1.1');
3270 curl_setopt($ch, CURLOPT_TIMEOUT, 60);
3271 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
3272 'Content-Type: application/json',
3273 'Content-Length: ' . strlen($data_string))
3274 );
3275
3276 $response = curl_exec($ch);
3277
3278 if (!curl_errno($ch)) {
3279 return $response;
3280 }
3281
3282 return false;
3283 }
3284 }
3285
3286 endif;
3287