Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Last active November 5, 2021 00:32
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save igorbenic/63438fb45fd42417ff9a02ea45177097 to your computer and use it in GitHub Desktop.
Save igorbenic/63438fb45fd42417ff9a02ea45177097 to your computer and use it in GitHub Desktop.
How to Create WooCommerce Refunds Programmatically | ibenic.com/how-to-create-woocommerce-refunds-programmatically
<?php
/**
* Process Order Refund through Code
* @return WC_Order_Refund|WP_Error
*/
function ibenic_wc_refund_order( $order_id, $refund_reason = '' ) {
$order = wc_get_order( $order_id );
// IF it's something else such as a WC_Order_Refund, we don't want that.
if( ! is_a( $order, 'WC_Order') ) {
return;
}
// Get Items
$order_items = $order->get_items();
// Refund Amount
$refund_amount = 0;
// Prepare line items which we are refunding
$line_items = array();
if ( $order_items = $order->get_items()) {
foreach( $order_items as $item_id => $item ) {
$item_meta = $order->get_item_meta( $item_id );
$product_data = wc_get_product( $item_meta["_product_id"][0] );
$item_ids[] = $item_id;
$tax_data = $item_meta['_line_tax_data'];
$refund_tax = 0;
if( is_array( $tax_data[0] ) ) {
$refund_tax = array_map( 'wc_format_decimal', $tax_data[0] );
}
$refund_amount = wc_format_decimal( $refund_amount ) + wc_format_decimal( $item_meta['_line_total'][0] );
$line_items[ $item_id ] = array( 'qty' => $item_meta['_qty'][0], 'refund_total' => wc_format_decimal( $item_meta['_line_total'][0] ), 'refund_tax' => $refund_tax );
}
}
$refund = wc_create_refund( array(
'amount' => $refund_amount,
'reason' => $refund_reason,
'order_id' => $order_id,
'line_items' => $line_items,
'refund_payment' => true
) );
return $refund;
}
<?php
/**
* Process Order Refund through Code
* @return WC_Order_Refund|WP_Error
*/
function ibenic_wc_refund_order( $order_id, $refund_reason = '' ) {
$order = wc_get_order( $order_id );
// If it's something else such as a WC_Order_Refund, we don't want that.
if( ! is_a( $order, 'WC_Order') ) {
return new WP_Error( 'wc-order', __( 'Provided ID is not a WC Order', 'yourtextdomain' ) );
}
if( 'refunded' == $order->get_status() ) {
return new WP_Error( 'wc-order', __( 'Order has been already refunded', 'yourtextdomain' ) );
}
// Get Items
$order_items = $order->get_items();
// Refund Amount
$refund_amount = 0;
// Prepare line items which we are refunding
$line_items = array();
// Other code will go here
}
<?php
/**
* Process Order Refund through Code
* @return WC_Order_Refund|WP_Error
*/
function ibenic_wc_refund_order( $order_id, $refund_reason = '' ) {
// ...
if ( $order_items ) {
foreach( $order_items as $item_id => $item ) {
$item_meta = $order->get_item_meta( $item_id );
$tax_data = $item_meta['_line_tax_data'];
$refund_tax = 0;
if( is_array( $tax_data[0] ) ) {
$refund_tax = array_map( 'wc_format_decimal', $tax_data[0] );
}
$refund_amount = wc_format_decimal( $refund_amount ) + wc_format_decimal( $item_meta['_line_total'][0] );
$line_items[ $item_id ] = array(
'qty' => $item_meta['_qty'][0],
'refund_total' => wc_format_decimal( $item_meta['_line_total'][0] ),
'refund_tax' => $refund_tax );
}
}
// Order Items were processed. We can now create a refund
}
<?php
/**
* Process Order Refund through Code
* @return WC_Order_Refund|WP_Error
*/
function ibenic_wc_refund_order( $order_id, $refund_reason = '' ) {
// ...
$refund = wc_create_refund( array(
'amount' => $refund_amount,
'reason' => $refund_reason,
'order_id' => $order_id,
'line_items' => $line_items,
'refund_payment' => true
));
return $refund;
}
@balistrerin
Copy link

I have a question about $refund_tax. I have orders that are digital downloads and have a VAT tax applied to them for certain European countries. When an order is refunded I also need the taxes to be refunded as well. The $refund_tax value is never set because $tax_data[0] is never an array. $tax_data is an array but not the first element. Is that the correct way to get the correct $refund_tax value or am I missing something?

@tharlab
Copy link

tharlab commented Feb 17, 2021

if you ask him here the original sourch, may you get fast respons there,
https://www.ibenic.com/how-to-create-woocommerce-refunds-programmatically/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment