I am using WooCommerce to sell some digital products. Due to the nature of our business, we do not want the item stock to go lower than 0 (-1, -2, etc.)
We are currently accepting different payment methods, including Cryptocurrency and Stripe. As the transaction speed of Crypto is low, it sometimes takes up to 1 hour, so we are facing issues like this:
When a user (User A) purchases an item and pays with Crypto, the item stock gets held (going from 1 to 0). As the blockchain is slow, it takes 2 hours to complete the payment. Since it's so slow, the item stock goes back from 0 to 1.
While the blockchain payment is still pending, a different user (User B) comes to buy the same product. At this time, the item is not being held anymore. Thus, this user gets the product. Item stock goes from 1 to 0.
The blockchain payment is finally confirmed. Woocommerce also gives the product to this user. Item stock goes from 0 to -1.
So 2 users get the same product.
I want to prevent for coinpayments and coinbase payment method Ids, changing order status from canceled to pending or from canceled to complete.
So I tried using the following code:
add_action('woocommerce_order_status_changed', 'prevent_status_change_after', 99, 4);
function prevent_status_change_after($order_id, $old_status, $new_status, $order) {
$payment_method = $order->get_payment_method();
if ($payment_method == 'coinbase' || $payment_method == 'coinpayments') {
if ($old_status == 'cancelled' && ($new_status == 'completed' || $new_status == 'pending')) {
// Optionally, add a note to the order
$order->add_order_note('Attempt to change status from "cancelled" was prevented.');
// Revert back to 'cancelled' status
remove_action('woocommerce_order_status_changed', 'prevent_status_change_after', 99);
$order->update_status('cancelled');
add_action('woocommerce_order_status_changed', 'prevent_status_change_after', 99, 4);
}
}
}
But it doesn't seem to be working.
Any help is appreciated.
Without any guaranty, try the following:
Code goes in functions.php file of your child theme (or in a plugin). It should work.