This repository has been archived by the owner on Nov 13, 2024. It is now read-only.
generated from a8cteam51/team51-plugin-scaffold
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up more lint issues; edit .gitignore
- Loading branch information
1 parent
0164400
commit 4c46e03
Showing
3 changed files
with
342 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
<?php | ||
|
||
namespace WPCOMSpecialProjects\SiftDecisions\Abuse_Decision_Actions; | ||
|
||
/** | ||
* Unblock a user from making purchases if Sift indicates that they are no longer a fraud risk. | ||
* | ||
* @param integer $user_id The ID of the user to unblock from making purchases. | ||
* | ||
* @return void | ||
*/ | ||
function unblock_user_from_purchases( $user_id ) { | ||
delete_user_meta( $user_id, 'is_blocked_from_purchases' ); | ||
} | ||
|
||
/** | ||
* Void and refund all orders for a user. | ||
* | ||
* @param integer $user_id The ID of the user to void and refund orders for. | ||
* | ||
* @return void | ||
*/ | ||
function void_and_refund_user_orders( $user_id ) { | ||
$orders = wc_get_orders( | ||
array( | ||
'customer' => $user_id, | ||
'status' => array( 'completed', 'processing' ), | ||
) | ||
); | ||
|
||
foreach ( $orders as $order ) { | ||
sift_fraud_void_refund_order( $order->get_id() ); | ||
} | ||
} | ||
|
||
/** | ||
* Cancel all subscriptions for a user. | ||
* | ||
* @param integer $user_id The ID of the user to cancel subscriptions for. | ||
* | ||
* @return void | ||
*/ | ||
function cancel_and_remove_user_subscriptions( $user_id ) { | ||
$subscriptions = wcs_get_users_subscriptions( $user_id ); | ||
|
||
foreach ( $subscriptions as $subscription ) { | ||
if ( 'active' === $subscription->get_status() || 'pending-cancel' === $subscription->get_status() ) { | ||
$subscription->update_status( 'cancelled', __( 'Cancelled by system due to account block. SGDC Error OYBPXRQ', 'sift-decisions' ) ); | ||
wp_delete_post( $subscription->get_id(), true ); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Remove licenses and product keys associated with a user. | ||
* | ||
* @param integer $user_id The ID of the user to remove licenses and product keys for. | ||
* | ||
* @return void | ||
*/ | ||
function remove_user_licenses_and_product_keys( $user_id ) { | ||
delete_user_meta( $user_id, 'user_licenses' ); | ||
delete_user_meta( $user_id, 'user_product_keys' ); | ||
|
||
$args = array( | ||
'post_type' => array( 'license', 'product_key' ), | ||
'meta_key' => 'user_id', | ||
'meta_value' => $user_id, | ||
'post_status' => 'any', | ||
); | ||
|
||
$posts = get_posts( $args ); | ||
foreach ( $posts as $post ) { | ||
wp_delete_post( $post->ID, true ); | ||
} | ||
} | ||
|
||
/** | ||
* Display the SGDC error to the user. | ||
* | ||
* @param string $message Override the default message to display to the user. | ||
* | ||
* @return void | ||
*/ | ||
function display_sgdc_error( $message = '' ) { | ||
$default_message = __( 'Your account has been blocked from making purchases. SGDC Error OYBPXRQ', 'sift-decisions' ); | ||
$message = $message ? $message : $default_message; | ||
wc_add_notice( $message, 'error' ); | ||
} | ||
|
||
/** | ||
* Force user logout when they are blocked from making purchases. | ||
* | ||
* @param integer $user_id The ID of the user to log out. | ||
* | ||
* @return void | ||
*/ | ||
function force_user_logout( $user_id ) { | ||
if ( class_exists( 'WP_Session_Tokens' ) ) { | ||
$user_sessions = WP_Session_Tokens::get_instance( $user_id ); | ||
$user_sessions->destroy_all(); | ||
} | ||
|
||
if ( get_current_user_id() === $user_id ) { | ||
wp_logout(); | ||
} | ||
} | ||
|
||
/** | ||
* To void/cancel/refund an order... | ||
* | ||
* Loosely based on https://www.ibenic.com/how-to-create-woocommerce-refunds-programmatically/ -- but needs review. | ||
* | ||
* @param mixed $order_id Post object or post ID of the order. | ||
* | ||
* @return \WC_Order_Refund|\WP_Error | ||
*/ | ||
function sift_fraud_void_refund_order( $order_id ) { | ||
$order = wc_get_order( $order_id ); | ||
|
||
if ( ! is_a( $order, 'WC_Order' ) ) { | ||
return new \WP_Error( | ||
'wc-order', | ||
__( 'Provided ID is not a WC Order', 'sift-decisions' ) | ||
); | ||
} | ||
|
||
if ( 'refunded' === $order->get_status() ) { | ||
return new \WP_Error( | ||
'wc-order', | ||
__( 'Order has been already refunded', 'sift-decisions' ) | ||
); | ||
} | ||
|
||
$order_items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) ); | ||
|
||
$refund_amount = 0; | ||
$line_items = array(); | ||
|
||
if ( ! $order_items ) { | ||
return new \WP_Error( | ||
'wc-order', | ||
__( 'This order has no items', 'sift-decisions' ) | ||
); | ||
} | ||
|
||
foreach ( $order_items as $item_id => $item ) { | ||
$line_total = $order->get_line_total( $item, false, false ); | ||
$qty = $item->get_quantity(); | ||
$tax_data = wc_get_order_item_meta( $item_id, '_line_tax_data' ); | ||
|
||
$refund_tax = array(); | ||
|
||
// Check if it's shipping costs. If so, get shipping taxes. | ||
if ( $item instanceof \WC_Order_Item_Shipping ) { | ||
$tax_data = wc_get_order_item_meta( $item_id, 'taxes' ); | ||
} | ||
|
||
// If taxdata is set, format as decimal. | ||
if ( ! empty( $tax_data['total'] ) ) { | ||
$refund_tax = array_filter( array_map( 'wc_format_decimal', $tax_data['total'] ) ); | ||
} | ||
|
||
// Calculate line total, including tax. | ||
$line_total_inc_tax = wc_format_decimal( $line_total ) + ( is_numeric( reset( $refund_tax ) ) ? wc_format_decimal( reset( $refund_tax ) ) : 0 ); | ||
|
||
// Add the total for this line to the grand total. | ||
$refund_amount += round( $line_total_inc_tax, 2 ); | ||
|
||
// Fill item per line. | ||
$line_items[ $item_id ] = array( | ||
'qty' => $qty, | ||
'refund_total' => wc_format_decimal( $line_total ), | ||
'refund_tax' => array_map( 'wc_round_tax_total', $refund_tax ), | ||
); | ||
} | ||
|
||
$refund = wc_create_refund( | ||
array( | ||
'amount' => $refund_amount, | ||
'reason' => 'Sift Fraud Detection - Voiding Order', | ||
'order_id' => $order->ID, | ||
'line_items' => $line_items, | ||
'refund_payment' => true, | ||
'restock_items' => true, | ||
) | ||
); | ||
|
||
return $refund; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<?php | ||
|
||
namespace WPCOMSpecialProjects\SiftDecisions\Abuse_Decisions; | ||
|
||
use function WPCOMSpecialProjects\SiftDecisions\Abuse_Decision_Actions\{ | ||
unblock_user_from_purchases, | ||
void_and_refund_user_orders, | ||
cancel_and_remove_user_subscriptions, | ||
remove_user_licenses_and_product_keys, | ||
display_sgdc_error, | ||
force_user_logout | ||
}; | ||
|
||
/** | ||
* Process the Sift decision received. | ||
* | ||
* @param mixed $return_value The return value. | ||
* @param string $decision_id The ID of the Sift decision. | ||
* @param integer $entity_id The ID of the entity the decision is for. | ||
* | ||
* @return mixed | ||
*/ | ||
function process_sift_decision_received( $return_value, $decision_id, $entity_id ) { | ||
|
||
switch ( $decision_id ) { | ||
case 'trust_list_payment_abuse': | ||
handle_trust_list_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'looks_good_payment_abuse': | ||
handle_looks_good_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'not_likely_fraud_payment_abuse': | ||
handle_not_likely_fraud_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'likely_fraud_refundno_renew_payment_abuse': | ||
handle_likely_fraud_refundno_renew_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'likely_fraud_keep_purchases_payment_abuse': | ||
handle_likely_fraud_keep_purchases_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'fraud_payment_abuse': | ||
handle_fraud_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'block_wo_review_payment_abuse': | ||
handle_block_wo_review_payment_abuse( $entity_id ); | ||
break; | ||
|
||
case 'looks_ok_payment_abuse': | ||
case 'looks_suspicious_payment_abuse': | ||
case 'order_looks_ok_payment_abuse': | ||
case 'order_looks_suspicious_payment_abuse': | ||
// Not Currently Implemented. | ||
break; | ||
} | ||
|
||
return $return_value; | ||
} | ||
add_filter( 'sift_decision_received', __NAMESPACE__ . '\process_sift_decision_received', 10, 5 ); | ||
|
||
/** | ||
* Handle the 'trust_list_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_trust_list_payment_abuse( $user_id ) { | ||
unblock_user_from_purchases( $user_id ); | ||
} | ||
|
||
/** | ||
* Handle the 'looks_good_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_looks_good_payment_abuse( $user_id ) { | ||
unblock_user_from_purchases( $user_id ); | ||
} | ||
|
||
/** | ||
* Handle the 'not_likely_fraud_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_not_likely_fraud_payment_abuse( $user_id ) { | ||
unblock_user_from_purchases( $user_id ); | ||
} | ||
|
||
/** | ||
* Handle the 'likely_fraud_refundno_renew_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_likely_fraud_refundno_renew_payment_abuse( $user_id ) { | ||
update_user_meta( $user_id, 'is_blocked_from_purchases', true ); | ||
void_and_refund_user_orders( $user_id ); | ||
cancel_and_remove_user_subscriptions( $user_id ); | ||
remove_user_licenses_and_product_keys( $user_id ); | ||
display_sgdc_error( 'You are blocked from making purchases due to a recent fraud review. SGDC Error OYBPXRQ' ); | ||
} | ||
|
||
/** | ||
* Handle the 'likely_fraud_keep_purchases_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_likely_fraud_keep_purchases_payment_abuse( $user_id ) { | ||
update_user_meta( $user_id, 'is_blocked_from_purchases', true ); | ||
display_sgdc_error( 'You are blocked from making purchases due to a recent fraud review. SGDC Error OYBPXRQ' ); | ||
} | ||
|
||
/** | ||
* Handle the 'fraud_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_fraud_payment_abuse( $user_id ) { | ||
update_user_meta( $user_id, 'is_blocked_from_purchases', true ); | ||
void_and_refund_user_orders( $user_id ); | ||
cancel_and_remove_user_subscriptions( $user_id ); | ||
remove_user_licenses_and_product_keys( $user_id ); | ||
display_sgdc_error( 'You are blocked from making purchases due to fraudulent activity. SGDC Error OYBPXRQ' ); | ||
force_user_logout( $user_id ); | ||
} | ||
|
||
/** | ||
* Handle the 'block_wo_review_payment_abuse' decision. | ||
* | ||
* @param integer $user_id The ID of the user. | ||
* | ||
* @return void | ||
*/ | ||
function handle_block_wo_review_payment_abuse( $user_id ) { | ||
update_user_meta( $user_id, 'is_blocked_from_purchases', true ); | ||
} |