Woocommerce subscription : apply coupon for renewal orders - woocommerce

I want to apply a coupon when a renewal order for a subscription is created.
I use stripe as payment gateway for woocommerce subscription.
I found the filter 'wcs_renewal_order_created' from the docs : https://docs.woocommerce.com/document/subscriptions/develop/filter-reference/
I manage to apply it, it's well trigger and I can apply a coupon to this order.
The order amount is reduce by the amount of the coupon.
Problem: Stripe charges the full amount of the order, without the discount. It's just like if the order I changed was not used by Stripe.
Here is the code sample, that reduce by 5 any renewal order :
function gens_renewal_order_created($order, $subscription){
$order = new WC_Order( $order->id );
$order->set_total($order->get_total() - 5);
return $order;
}

This is a bit late but there has been no reply.
If you take a look at 'wcs_create_order_from_subscription()'
This the function where the new order is created. here also has a different filter that isn't mentioned within the documentation 'wcs_new_order_created'.
So here is what your code should be.
function gens_renewal_order_created($order, $subscription){
$order = new WC_Order( $order->id );
$order->set_total($order->get_total() - 5);
return $order;
}
add_filter('wcs_new_order_created','gens_renewal_order_created', 10, 2 );

Related

Update ACF custom fields for new WooCommerce order

I'm trying to update 2 ACF custom fields every time an order is created.
We have orders coming from our own website and orders coming from an external marketplace integration. My goal is to differentiate the 2 type of orders using custom fields in the order.
The data for the custom fields is provided by an external marketplace integration. The first field has to be filled with the ordernumber (if it it exists) and the other field is just a simple true/false field.
For website orders we're using "Free shipping". For external orders, the provided shipping details are as follows:
Shipping "Verzending voor bol(xxxxx)"
I'm trying to get the shipping method using the woocomerce_new_order action, and using $order->get_shipping_method()
However, when a new order is created, the custom fields won't update.
This is what I've tried so far:
add_action( 'woocommerce_new_order', 'vliegwerk_bolcom_order_filter', 99, 2);
function vliegwerk_bolcom_order_filter( $order_id, $order ) {
$order = wc_get_order( $order_id );
$verzendmethode = $order->get_shipping_method();
$bol_ordernummer = (int) filter_var($verzendmethode, FILTER_SANITIZE_NUMBER_INT);
if ($bol_ordernummer > 0) {
update_field('field_61fa977c8dff9', $bol_ordernummer, $order_id );
update_field('field_61fa95f594b13', 1, $order_id );
}
}
I already tested the woocommerce_new_order trigger, it works as expected.
I've also tried updating the fields using a foreach loop, and triggering the function with a shortcode. This also works as expected.
However, when combining it all together, the fields won't update. Any help would be appreciated!

Woocommerce DISABLE autocomplete € 0 orders

I wish i could just use Uncle Google but he serve me only what i DON'T want :D
I have a free Product on my website. But I want to check every order manualy, because it's only for company accounts and not for "customers".
But every order will set the Status to approved - or what ever in english language- and the order is complete.
The user has automaticaly acces to "restricted area" and that's what I don't want. I want to check every order manualy and pick every spam account.
I can imagine, this is going to work with only one simple function but I can't get it. It's only one free Product, other Products are for moneeeeey.
It would be great if somebody has the same issue and can help me :)
Thank you
Place the following function in your active theme functions.php. Check all default statuses here and change on-hold to what you want - https://woocommerce.wp-a2z.org/oik_api/wc_get_order_statuses/
function change_free_order_status( $order_id ) {
if ( ! $order_id ) {return;}
$order = wc_get_order( $order_id );
if($order->get_total() <= 0):
$order->update_status( 'on-hold' ); // Change to what you need
endif;
}
add_action('woocommerce_thankyou','change_free_order_status');

Payment methods not showing if cart total is 0 in WooCommerce

I'm setting up a store for a client with multiples user roles. One of them need to have prices of 0$ because the company's billed monthly. Others roles have to pay differents prices with multipliers depending on their roles using "Product Price by User Role".
Anyway, when a user buy some products for 0$ the COD method's not showing and i need that payment gateway to set a custom status.
Anyone encountered the problem before? If so, any guidance is appreciated!
"Anyone encountered the problem before?". This is default behavior in WooCommerce
To prevent this, use:
// Looks at the totals to see if payment is actually required.
function filter_woocommerce_cart_needs_payment( $needs_payment, $cart ) {
// Set true
$needs_payment = true;
return $needs_payment;
}
add_filter( 'woocommerce_cart_needs_payment', 'filter_woocommerce_cart_needs_payment', 10, 2 );
Or in short
add_filter( 'woocommerce_cart_needs_payment', '__return_true' );
AND
// Checks if an order needs payment, based on status and order total.
function filter_woocommerce_order_needs_payment( $needs_payment, $order, $valid_order_statuses ) {
// Set true
$needs_payment = true;
return $needs_payment;
}
add_filter( 'woocommerce_order_needs_payment', 'filter_woocommerce_order_needs_payment', 10, 3 );
Or in short
add_filter( 'woocommerce_order_needs_payment', '__return_true' );

woocommerce recalculate price programmatically

11/5/21 Update
It's really tricky that find out the wc_order couldn't access the calculate_totals and calculate_taxes.I find out the solution is put $order = wc_get_order( $order->get_id() ); before calulation. The 2 $order type is different , one is (object)WC_Order and another one is (Object)Automattic\WooCommerce\Admin\Overrides\Order. The method of second object works.
I wanna make the AJAX function to place an order programmatically. The product price is base on metadata so I have to calculate every line item. It doesn't with any issue from the client side that sends the post the request to place. The problem point, even I set the price to the line item, and use calculate_totals for the WC_Order but the price didn't correct. The only correction is the cost and subtotal. Though I hit the recalculate button the price would be right.
code
function place_an_order($data){
$screen_prodcut = new WC_Product_Simple(6310);
$userid = get_current_user_id();
$order = wc_create_order(array('customer_id'=>$userid));
$screen_quantity = 2;
$item_id = $order->add_product($screen_prodcut,$screen_quantity);
wc_add_order_item_meta($item_id,'width','1201');
wc_add_order_item_meta($item_id,'height','1201');
wc_add_order_item_meta($item_id,'note','** this is testing**');
$screen_price = 50;
$new_line_screen_price = $screen_price * $screen_quantity;
$item = $order->get_item($item_id);
$item->set_subtotal( $new_line_screen_price / 11 * 10 );
$item->set_total( $new_line_screen_price / 11 * 10 );
$item->save();
// ###section 1###
$order->calculate_taxes();
$order->calculate_totals();
// ###section 2###
}
When run in section 1, the $item subtotal and total are correct. But run in section 2 there is the failure out when printing $order and retrieve the total is wrong. In the dashboard, the price would be shown wrong but the total and subtotal are correct.
After clicking the recalculate, the order total is corrected.
I have no idea why calculate_totals and calculate_taxes don't work. woocommerce_calc_line_taxes is the AJAX action via hit the recalculate button. Usage is calculate_totals and taxes as well. Alternatively, I have to use the set_total instead of calculate_totals?

How do you get current renewal order id for woocommerce subscriptions?

I'm using woocommerce subscriptions with the custom function like below and can only get the parent order id from $subscription (from the order that initiated the subscription rather than getting each new order ID as renewals get triggered). Does anyone know how to get each new recurring order id?
add_action( 'woocommerce_scheduled_subscription_payment', 'record_parent_referral_on_payment' );
function record_parent_referral_on_payment( $subscription ) {
....

Resources