Johan Rheeder
Johan Rheeder

Reputation: 319

Issue with Woocommerce wc_create_refund

We want to create a refund from a webhook but the refunded amount seems to triple the refunded amount.

Below is what we have for the code and this is only triggered once.

$order_id = (isset($_REQUEST["order_id"]) && strlen($_REQUEST["order_id"]) > 0) ? intval($_REQUEST["order_id"]) : false;
$amount = (isset($_REQUEST["amount"]) && strlen($_REQUEST["amount"]) > 0) ? floatval($_REQUEST["amount"]) : false;
$reason = (isset($_REQUEST["reason"]) && strlen($_REQUEST["reason"]) > 0) ? $_REQUEST["reason"] : false;
if ($order_id) {
    $order = wc_get_order($order_id);
    if ($order->get_remaining_refund_amount() >= $amount) {
        $refund = wc_create_refund(array(
            'amount' => $amount,
            'reason' => $reason,
            'order_id' => $order_id,
            'refund_payment' => true
        ));
        if (is_wp_error($refund)) {
            if ($refund->get_error_message() == 'Invalid refund amount.') {

                echo 'Refund requested exceeds remaining order balance of ' . $order->get_formatted_order_total();
            } else {
                echo $refund->get_error_message();
            }
        } else {
            echo $refund->get_id();
        }
    } else {
        echo 'Refund requested exceeds remaining order balance of ' . $order->get_formatted_order_total();
    }

}

But as you can see from this screenshot below, it seems to triple the refunded value but not sure why

enter image description here

Can anyone shed some light on why this might happen.

The request comes in as a post http request with a unique key identifier. eg

https://example.com/process-refunds/?key=ff5f61b5a9d6ff2a5d7fb9fc815113d4&order_id=1234&amount=100&reason=Testing

Upvotes: 3

Views: 2581

Answers (2)

Outsource WordPress
Outsource WordPress

Reputation: 3809

Try calling the function in init hook (add to your theme's 'functions.php') which working fine for me.

add_action( 'init', 'wc_manual_refund' );

function wc_manual_refund()
{
    $order_id = (isset($_REQUEST["order_id"]) && strlen($_REQUEST["order_id"]) > 0) ? intval($_REQUEST["order_id"]) : false;
    $amount = (isset($_REQUEST["amount"]) && strlen($_REQUEST["amount"]) > 0) ? floatval($_REQUEST["amount"]) : false;
    $reason = (isset($_REQUEST["reason"]) && strlen($_REQUEST["reason"]) > 0) ? $_REQUEST["reason"] : false;

    if ($order_id) {
        $order = wc_get_order($order_id);

        if ($order->get_remaining_refund_amount() >= $amount) {
            $refund = wc_create_refund(array(
                'amount' => $amount,
                'reason' => $reason,
                'order_id' => $order_id,
                'refund_payment' => true
            ));
            if (is_wp_error($refund)) {
                if ($refund->get_error_message() == 'Invalid refund amount.') {
                    echo 'Refund requested exceeds remaining order balance of ' . $order->get_formatted_order_total();
                } else {
                    echo $refund->get_error_message();
                }
            } else {
                echo $refund->get_id();
            }
        } else {
            echo 'Refund requested exceeds remaining order balance of ' . $order->get_formatted_order_total();
        }       
    }
}

Upvotes: 2

dineshkashera
dineshkashera

Reputation: 1502

Check condition with get max refund amount. And Ensure your code runs only once by using static variable.

static $result;

$order = wc_get_order($order_id);

$max_refund = wc_format_decimal($order->get_total() - $order->get_total_refunded());
    if (!$max_refund) {
      return;
    }

if($result == null){
// Create the refund object
$refund = wc_create_refund(array('amount' => $max_refund, 'reason' => __('Order Fully Refunded', 'woocommerce'), 'order_id' => $order_id, 'line_items' => array()));
wc_delete_shop_order_transients($order_id);

} 
$result = 'code-already-run';

I hope it will help you.

Upvotes: 1

Related Questions