How to programmatically refund a specific fee on Woocommerce
Answer a question
Here's the exact thing I'm trying to do.
For every orders placed on my WC website, I'm programmatically calculating and adding a fee with a specific name ('RCP'), depending on product attributes.
Let's say that Product A adds 5€, Product B adds 7€,then I'm getting a taxable fee of 12€ (+20% VAT = 14.4€).
But of course when I refund product A, creating a partial refund, it doesn't refund the 5€ on the fee. For orders with large amount of products, it's obviously too complicated for my employee to calculate him/herself how much of the fee is refunded everytime + the new VAT.
I added a hook at 'woocommerce_create_refund' to insert a new $item to my $refund object and then save it. For some reason, it's not working. I based myself on this "https://www.ibenic.com/how-to-create-woocommerce-refunds-programmatically/".
I tried creating an order fee object, but then it's not refunding my original fee item ('RCP').
What am I doing wrong ? Is it possible to refund my specific fee item partially, programmatically ?
Thank you so much in advance for your help.
Answers
So instead of using php and wordpress hooks, I used client side JS to live calculate how much of the Fee Item will be refunded.
Explained :
1/ In order for this to works I had to add a custom hidden column in the wp admin order table through this :
add_action('woocommerce_admin_order_item_values', 'add_stock_status_value_on_order_item_view');
function add_stock_status_value_on_order_item_view($_product)
{
if(!$_product) return;
?>
<td style="display:none;" class="sku">
<?php echo $_product->get_sku();?>
</td><?php
}
2/ Live calculate the fee refund on every quantity button click event. As the fee is only applied to France customers, I'm checking the shipping country as well. I'm copy pasting the unminified version.
What it's doing, on order item qty button click :
- Check if the shipping country is France
- Get the refunded product qty and its sku
- Regex testing the SKU.
- How much GB capacity => how much of the fee will be refunded
- Updating the total fee refund + VAT AND the global refund input (otherwise it just doesn't work).
The code :
jQuery(".post-type-shop_order form#post").one("submit", function (e) {
e.preventDefault(),
jQuery(".post-type-shop_order form#post .add-items button.calculate-action").click(),
setTimeout(function () {
e.currentTarget.submit();
}, 4e3);
}),
jQuery(".refund_order_item_qty").bind("click", function (e) {
if (((country = jQuery("#_shipping_country").find(":selected").val()), "FR" === country)) {
var t = 0,
i = 0;
jQuery("#order_line_items .refund_order_item_qty").each(function () {
if (jQuery(this).val() > 0) {
(q = jQuery(this).val()), (sku = jQuery(this).closest(".item").find(".sku").text()), (sku = sku.replace(/\s+/g, ""));
var e = new RegExp("(?<=_)([0-9]*)(?=GB)");
if (sku.includes("TSM_MAC")) return;
if (sku.includes("IW")) return;
if (sku.endsWith("_D")) return;
e.test(sku) &&
((gb = sku.match(e)),
(gb = +gb[0]),
(ipad = sku.includes("IPAD")),
1 == ipad
? 8 == gb || 16 == gb
? (coef = 5.2)
: 32 == gb
? (coef = 6.5)
: 64 == gb
? (coef = 7.8)
: gb > 64 && (coef = 9.1)
: 8 == gb
? (coef = 2.4)
: 16 == gb
? (coef = 4.8)
: 32 == gb
? (coef = 6)
: 64 == gb
? (coef = 7.2)
: gb > 64 && (coef = 8.4),
(t += q * coef));
} else (fee_item = jQuery("#order_fee_line_items > .fee")), jQuery(fee_item).find(".refund_line_total").val(0).change(), jQuery(fee_item).find(".refund_line_tax[data-tax_id=1]").val(0).change();
}),
t > 0 &&
((fee_item = jQuery("#order_fee_line_items > .fee")),
jQuery(fee_item).length &&
((i += 0.2 * t), jQuery(fee_item).find(".refund_line_total").val(t.toLocaleString("fr-FR")).change(), jQuery(fee_item).find(".refund_line_tax[data-tax_id=1]").val(i.toLocaleString("fr-FR")).change()));
}
});
更多推荐
所有评论(0)