I was looking for a solution to the same problem – I couldn’t find any help with this online but I was able to figure it out myself, so for anyone else here is the solution:
Change the hook from woocommerce_order_refunded
to woocommerce_order_partially_refunded
. This will only fire when an order is partially refunded. If you refund the full remaining quantity of items in the order then the order status will change to Refunded and the woocommerce_order_refunded
hook will fire instead.
Below is the working code for this question. Be sure to click the Recalculate button on the Edit Order screen after processing a partial refund – I discovered a bug in WooCommerce when issuing additional partial refunds separately for a different line item in the same order – the original refund amount will get changed incorrectly. The recalculate button fixes this but only if you press it before issuing proceeding partial refunds.
function action_woocommerce_order_refunded( $order_id, $refund_id )
{
//init
$restock_items = $_POST['restock_refunded_items'];
// If restock isn't checked skip
if( $restock_items == 'true' ) {
$refund = wc_get_order( $refund_id );
$refunded_items = $refund->get_items();
foreach( $refunded_items as $refunded_item_id => $refunded_item ) {
$refunded_quantity = $refunded_item->get_quantity(); // returns negative number e.g. -1
$refunded_quantity = $refunded_quantity *-1; // convert to positive number
$refunded_product_id = $refunded_item->get_product_id();
$usa_stock_toggle = get_post_meta( $refunded_product_id, '_usa_stock_toggle', true );
if( !empty( $usa_stock_toggle ) ){
$usa_stock_levels = get_post_meta( $refunded_product_id '_usa_stock_field', true ); // Get stock level
$updated_usa_stock_levels = $usa_stock_levels + $refunded_quantity; // Work out new stock level
update_post_meta( $refunded_product_id, '_usa_stock_field', $updated_usa_stock_levels ); // Update stock level
}
}
}
}
add_action( 'woocommerce_order_partially_refunded', 'action_woocommerce_order_refunded', 10, 2 );
You would need to calculate the difference of a refunded quantity when an order changes from partially refunded to fully refunded, I started working on this but haven’t found the solution yet.
You also might want to look at using the hook woocommerce_refund_deleted
in case you need to delete a refund that was issued by mistake and need to restock your metadata.