wc_create_refund

Create a new order refund programmatically.

Description

(WC_Order_Refund|WP_Error) wc_create_refund( (array) $args = array() ); 

Returns a new refund object on success which can then be used to add additional data.

Returns (WC_Order_Refund|WP_Error)

Parameters (1)

0. $args — Optional. (array) => array()
The args.

Usage

  1. if ( !function_exists( 'wc_create_refund' ) ) { 
  2. require_once ABSPATH . PLUGINDIR . 'woocommerce/includes/wc-order-functions.php'; 
  3.  
  4. // The args. 
  5. $args = array(); 
  6.  
  7. // NOTICE! Understand what this does before running. 
  8. $result = wc_create_refund($args); 
  9.  

Defined (1)

The function is defined in the following location(s).

/includes/wc-order-functions.php  
  1. function wc_create_refund( $args = array() ) { 
  2. $default_args = array( 
  3. 'amount' => 0,  
  4. 'reason' => null,  
  5. 'order_id' => 0,  
  6. 'refund_id' => 0,  
  7. 'line_items' => array(),  
  8. 'refund_payment' => false,  
  9. 'restock_items' => false,  
  10. ); 
  11.  
  12. try { 
  13. $args = wp_parse_args( $args, $default_args ); 
  14.  
  15. if ( ! $order = wc_get_order( $args['order_id'] ) ) { 
  16. throw new Exception( __( 'Invalid order ID.', woocommerce ) ); 
  17.  
  18. $remaining_refund_amount = $order->get_remaining_refund_amount(); 
  19. $remaining_refund_items = $order->get_remaining_refund_items(); 
  20. $refund_item_count = 0; 
  21. $refund = new WC_Order_Refund( $args['refund_id'] ); 
  22.  
  23. if ( 0 > $args['amount'] || $args['amount'] > $remaining_refund_amount ) { 
  24. throw new Exception( __( 'Invalid refund amount.', woocommerce ) ); 
  25.  
  26. $refund->set_currency( $order->get_currency() ); 
  27. $refund->set_amount( $args['amount'] ); 
  28. $refund->set_parent_id( absint( $args['order_id'] ) ); 
  29. $refund->set_refunded_by( get_current_user_id() ? get_current_user_id() : 1 ); 
  30.  
  31. if ( ! is_null( $args['reason'] ) ) { 
  32. $refund->set_reason( $args['reason'] ); 
  33.  
  34. // Negative line items 
  35. if ( sizeof( $args['line_items'] ) > 0 ) { 
  36. $items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) ); 
  37.  
  38. foreach ( $items as $item_id => $item ) { 
  39. if ( ! isset( $args['line_items'][ $item_id ] ) ) { 
  40. continue; 
  41.  
  42. $qty = isset( $args['line_items'][ $item_id ]['qty'] ) ? $args['line_items'][ $item_id ]['qty'] : 0; 
  43. $refund_total = $args['line_items'][ $item_id ]['refund_total']; 
  44. $refund_tax = isset( $args['line_items'][ $item_id ]['refund_tax'] ) ? array_filter( (array) $args['line_items'][ $item_id ]['refund_tax'] ) : array(); 
  45.  
  46. if ( empty( $qty ) && empty( $refund_total ) && empty( $args['line_items'][ $item_id ]['refund_tax'] ) ) { 
  47. continue; 
  48.  
  49. $class = get_class( $item ); 
  50. $refunded_item = new $class( $item ); 
  51. $refunded_item->set_id( 0 ); 
  52. $refunded_item->add_meta_data( '_refunded_item_id', $item_id, true ); 
  53. $refunded_item->set_total( wc_format_refund_total( $refund_total ) ); 
  54. $refunded_item->set_taxes( array( 'total' => array_map( 'wc_format_refund_total', $refund_tax ), 'subtotal' => array_map( 'wc_format_refund_total', $refund_tax ) ) ); 
  55.  
  56. if ( is_callable( array( $refunded_item, 'set_subtotal' ) ) ) { 
  57. $refunded_item->set_subtotal( wc_format_refund_total( $refund_total ) ); 
  58.  
  59. if ( is_callable( array( $refunded_item, 'set_quantity' ) ) ) { 
  60. $refunded_item->set_quantity( $qty * -1 ); 
  61.  
  62. $refund->add_item( $refunded_item ); 
  63. $refund_item_count += $qty; 
  64.  
  65. $refund->update_taxes(); 
  66. $refund->calculate_totals( false ); 
  67. $refund->set_total( $args['amount'] * -1 ); 
  68.  
  69. /** 
  70. * Action hook to adjust refund before save. 
  71. * @since 3.0.0 
  72. */ 
  73. do_action( 'woocommerce_create_refund', $refund, $args ); 
  74.  
  75. if ( $refund->save() ) { 
  76. if ( $args['refund_payment'] ) { 
  77. $result = wc_refund_payment( $order, $refund->get_amount(), $refund->get_reason() ); 
  78.  
  79. if ( is_wp_error( $result ) ) { 
  80. $refund->delete(); 
  81. return $result; 
  82.  
  83. if ( $args['restock_items'] ) { 
  84. wc_restock_refunded_items( $order, $args['line_items'] ); 
  85.  
  86. // Trigger notification emails 
  87. if ( ( $remaining_refund_amount - $args['amount'] ) > 0 || ( $order->has_free_item() && ( $remaining_refund_items - $refund_item_count ) > 0 ) ) { 
  88. do_action( 'woocommerce_order_partially_refunded', $order->get_id(), $refund->get_id() ); 
  89. } else { 
  90. do_action( 'woocommerce_order_fully_refunded', $order->get_id(), $refund->get_id() ); 
  91.  
  92. $parent_status = apply_filters( 'woocommerce_order_fully_refunded_status', 'refunded', $order->get_id(), $refund->get_id() ); 
  93.  
  94. if ( $parent_status ) { 
  95. $order->update_status( $parent_status ); 
  96.  
  97. do_action( 'woocommerce_refund_created', $refund->get_id(), $args ); 
  98. do_action( 'woocommerce_order_refunded', $order->get_id(), $refund->get_id() ); 
  99.  
  100. } catch ( Exception $e ) { 
  101. return new WP_Error( error, $e->getMessage() ); 
  102.  
  103. return $refund;