Converting the order from processing to complete in WooCommerce (WordPress) - php

I used artificial intelligence for the first time
But the code you told me is not working
To convert veins automatically from treatment to complete after 30 seconds
Only on virtual products
There are two specific payment methods
But it doesn't work
// Add a 30 second delay for virtual products
add_filter( 'woocommerce_payment_complete_order_status', 'wc_delay_virtual_order', 10, 2 );
function wc_delay_virtual_order( $order_status, $order ) {
if ( $order->has_downloadable_item() && ! $order->has_status( 'completed' ) ) {
return 'on-hold'; // change to any other status you wish to use.
}
return $order_status;
}
add_action( 'woocommerce_thankyou', 'wc_delay_virtual', 30 );
function wc_delay_virtual( $orderid ) {
// Get the order object and check for downloadable items.
$order = new WCOrder($orderid);
if ( $order->hasDownloadableItem() ) {
// Set a 30 second delay for virtual products.
sleep(30);
// Update the order status to complete.
$order->updateStatus('completed');
}
}
// Add a custom payment gateway for MobileWallet and Reference Code payments.
add-filter('woocommerce-payment-gateways','wc-add-mobilewallet-referencecode');
function wc-add-mobilewallet-referencecode($methods){
$methods[] = 'WCMobileWallet'; // MobileWallet payment gateway class name.
$methods[] = 'WCReferenceCode'; // Reference Code payment gateway class name.
return $methods;
}
I tried to add this code inside plugin and inside function.php
I am waiting for your response to solve my problem, thank you

The part of your code posted below has an issue. you cant use - in between function name like wc-add-mobilewallet-referencecode instead it should be wc_add_mobilewallet_referencecode using and underscore "_"
Your correct code should look so:
add_filter('woocommerce-payment-gateways','wc_add_mobilewallet_referencecode');
function wc_add_mobilewallet_referencecode($methods){
$methods[] = 'WCMobileWallet'; // MobileWallet payment gateway class name.
$methods[] = 'WCReferenceCode'; // Reference Code payment gateway class name.
return $methods;
}
And since you just need to change order status to complete on downloadable product, just need the code below:
add_filter( 'woocommerce_payment_complete_order_status', 'wc_delay_virtual_order', 10, 2 );
function wc_delay_virtual_order( $order_status, $order ) {
if ( $order->has_downloadable_item() && ! $order->has_status( 'completed' ) ) {
sleep(30);
return 'completed'; //Here should be complete.
}
return $order_status;
}

The requirement doesn't seem to work for the following reasons:
Payment gateways will have their configuration where after each successful order, the status will be updated based on the configuration.
Making the customer wait 30 seconds on the browser is not recommended.
Even if you forcefully update the order status on the thankyou page hook, what will happen next is if the woocommerce or any third-party plugin or payment plugin has different order statuses, those will be updated as soon as your update is done.
Nevertheless, there are three possible ways for your requirement.
Search for payment configuration and update the order completion status there. For example, in the case of Novalnet Payment Gateway, I use their configuration, so I need not do anything here.
On the WooCommerce shop backend, you have the settings you can use it. Refer https://woocommerce.com/document/woocommerce-order-status-control/
Based on your business logic, you can set up a cron to update all the virtual orders that aren't on complete order status. Refer https://developer.wordpress.org/plugins/cron/

Related

WooCommerce order status hook not triggering

I'm using this little function here to detect if an order is set into pending. This happens between the payment page and the payment provider notification:
add_action( 'woocommerce_order_status_pending', 'status_pending' );
function status_pending( $related_job ) {
error_log('Triggered');
}
The problem is that I don't get any error log which shows me that the function work. But it becomes crazier. When I update the status via the dashboard from completed to pending, the log appears. So I've absolutely no idea why it's not working during the checkout process. Any recommendations or ideas what could be the problem?
The "pending" order status is the default status for orders before customer get on a payment gateway, just after order creation.
So the best way is to use a hook once the order is created, before payment method process:
1) try first the woocommerce_checkout_order_processed action hook (3 args):
add_action( 'woocommerce_checkout_order_processed', 'order_processed_with_pending_status', 10, 3 );
function order_processed_with_pending_status( $order_id, $posted_data, $order ) {
error_log('Triggered');
}
2) Alternatively try the woocommerce_checkout_update_order_meta action hook (2 args):
add_action( 'woocommerce_checkout_update_order_meta', 'order_processed_with_pending_status', 10, 2 );
function order_processed_with_pending_status( $order_id, $data ) {
error_log('Triggered');
}
Both should work…
That's because the hook is only triggering on order status change not on order creation, there is another hook that you can use to detect new orders, you can use the order ID to get order object which you can use to find out the order status:
add_action( 'woocommerce_new_order', 'prefix_new_wc_order', 1, 1 );
function prefix_new_wc_order( $order_id ) {
$order = new WC_Order( $order_id );
}
The hook above is only triggered in checkout process, so creating orders on backend won't trigger it.

Change order status to refund when a paid booking is cancelled in Woocommerce booking

I am using Woocommerce with Woocommerce Booking plugin and I would like to update the order status to refunded every time a paid booking is cancelled.
I've found some answers on StackOverFlow, but still can't manage to solve this requirement.
I know I might be completely wrong, but this the last try I made and obviously it didn't work:
add_action('woocommerce_booking_paid_to_cancelled','change_status_to_refund', 10, 2);
function change_status_to_refund($booking_id, $order_id) {
$booking = new WC_Order($booking_id);
$order = new WC_Order($order_id);
$booking_status = $booking->get_status();
if($booking_status != 'paid'){
$order->update_status('refund', 'order_note');
}
}
Any help is welcome.
You are not using the correct arguments for woocommerce_booking_{ status_from }_to_{ status_to } action hook in your function, which are:
The booking ID: $booking_id,
The Booking Object $booking.
So you need to get the Order from the Booking in your code, to be able to update the Order status.
Note: The condition $booking_status != 'paid' is not really needed.
So your code will be much simpler and effective:
add_action('woocommerce_booking_paid_to_cancelled','cancelled_booking_order_status_cahnged_to_refund', 10, 2);
function cancelled_booking_order_status_cahnged_to_refund( $booking_id, $booking ) {$
// Get the WC_Order object from a booking
$order = wc_get_order( wp_get_post_parent_id( $booking_id ) );
// Update order status
if( is_a($order, 'WC_Order') )
$order->update_status('refund');
}
Code goes on function.php file of your active child theme (or active theme). It should works.
Documentation: Woocommerce booking developer documentation for filter and action hooks

WooCommerce Check if order is paid/processing or completed

Im trying to set a value "paid" in my custom table when the payment was successful / the customer gets redirectd to the thankyou page.
Im not sure if its secure enough to insert "paid => 1" just when the buyer reached the thankyou page. Thats why i wanted to check if the order was really paid, completed or processing.
Now i figured some payment methods are slow? When i checkout with Klarna my method works and it inserts paid = 1, but when I choose Paypal my Method will die and return: "WASNT PAID". But when I refresh the thankyou-page like 30 secs later it works. So i came to the conclusion that the order_status isnt set fast enough? Is there a cleaner way than mine?
add_action('woocommerce_thankyou', 'ceb_order_complete', 10, 1);
function ceb_order_complete( $order_id ) {
if ( ! $order_id )
return;
// Getting an instance of the order object
$order = wc_get_order( $order_id );
if($order->is_paid() || $order->has_status('processing') || $order->has_status('completed')) {
global $wpdb;
$payID = WC()->session->get( 'payID' );
if(!empty($payID)) {
if(!$wpdb->update($wpdb->prefix."ceb_registrations", array("paid"=>1), array("payID"=>$payID))) {
die("ERROR IN PAYMENT COMPLETE");
}
}
} else {
die("WASNT PAID");
}
}
"woocommerce_thankyou" hook will run each time you see/refresh thankyou page.
The most suitable way is to process data after payment received. For that you can use "woocommerce_payment_complete".
add_action('woocommerce_payment_complete', 'payment_complete_callback');
function payment_complete_callback($order_id)
{
$order = wc_get_order($order_id);
$user = $order->get_user();
// do what ever you want to do using $order object of the WC_Order class providing many functions
}

Set Woocommerce new orders to "On hold" without going to "Processing"

Is it possible to set all new orders to on hold without them going to processing first?
I need to capture the funds, but the order needs to go as on-hold rather than processing so that I can make sure the payment is received before triggering the email to our supplier.
I have found some code that allows me to change all new orders to on-hold, however when payment is authorized the order is set to processing.
pending payment --> processing (triggers email) --> on-hold
Screenshot of Order Notes that show this
This is the code that I found:
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_onhold_order' );
function custom_woocommerce_auto_onhold_order( $order_id ) {
global $woocommerce;
if ( !$order_id )
return;
$order = new WC_Order( $order_id );
$order->update_status( 'on-hold' ); //All new orders go to "on-hold"
}
I've been looking for the action which triggers the order status to be set to processing on payment authorization however I cannot find it.
All help is greatly appreciated!
Edit: I've managed to stumble upon a snippet of code that appears to work.
add_filter( 'woocommerce_payment_complete_order_status', 'custom_update_order_status', 10, 2 );
function custom_update_order_status( $order_status, $order_id ) {
return 'on-hold';
}
All orders start with a "pending" status in Woocommerce. That status is set before they go through the payment gateway...
There is no email notifications for "Pending" orders staus
You can try the following, that will set the status "on-hold" on order creation (The update status action comes once the order has been created ans saved in database):
add_action( 'woocommerce_checkout_create_order', 'force_new_order_status', 20, 1 );
function force_new_order_status( $order ) {
if( ! $order->has_status('on-hold') )
$order->set_status( 'on-hold', 'Forced status by a custom script' );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Set WooCommerce order status when order is created from processing to pending

When a woocommerce order is created the status of the order is "processing". I need to change the default order-status to "pending".
How can I achieve this?
The default order status is set by the payment method or the payment gateway.
You could try to use this custom hooked function, but it will not work (as this hook is fired before payment methods and payment gateways):
add_action( 'woocommerce_checkout_order_processed', 'changing_order_status_before_payment', 10, 3 );
function changing_order_status_before_payment( $order_id, $posted_data, $order ){
$order->update_status( 'pending' );
}
Apparently each payment method (and payment gateways) are setting the order status (depending on the transaction response for payment gateways)…
For Cash on delivery payment method, this can be tweaked using a dedicated filter hook, see:
Change Cash on delivery default order status to "On Hold" instead of "Processing" in Woocommerce
Now instead you can update the order status using woocommerce_thankyou hook:
add_action( 'woocommerce_thankyou', 'woocommerce_thankyou_change_order_status', 10, 1 );
function woocommerce_thankyou_change_order_status( $order_id ){
if( ! $order_id ) return;
$order = wc_get_order( $order_id );
if( $order->get_status() == 'processing' )
$order->update_status( 'pending' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works
Note: The hook woocommerce_thankyou is fired each time the order received page is loaded and need to be used with care for that reason...
Now the function above will update the order status only the first time. If customer reload the page, the condition in the IF statement will not match anymore and nothing else will happen.
Related thread: WooCommerce: Auto complete paid Orders (depending on Payment methods)
Nowadays, if the payment gateway that you use properly sets the order status using WC_Order->payment_complete(), you can use the woocommerce_payment_complete_order_status filter.
This is better than using woocommerce_thankyou hook since we are setting the order status immediately, rather than applying it after it has been already set.
function h9dx3_override_order_status($status, $order_id, $order) {
if ($status === 'processing') {
$status = 'pending';
}
return $status;
}
add_filter('woocommerce_payment_complete_order_status', 'h9dx3_override_order_status', 10, 3);
Again, this will only work if the payment gateway uses the proper payment_complete wrapper method rather than setting status directly with set_status. You can just search the gateway code for 'payment_complete(' and 'set_status(' to see what it does.
If you develop a plugin for everyone, you will be better off with using woocommerce_thankyou, or you could use a combined approach and use woocommerce_thankyou as the fallback if the order status was not updated.
The hook woocommerce_thankyou suffers from the problem that you can pay for an order and then close the browser or go somewhere else and therefore never click "Return to Merchant" (which is displayed after paying via paypal) to get to the thankyou page. And then the code will never be executed.
// Rename order status 'Processing' to 'Order Completed' in admin main view - different hook, different value than the other places
add_filter( 'wc_order_statuses', 'wc_renaming_order_status' );
function wc_renaming_order_status( $order_statuses ) {
foreach ( $order_statuses as $key => $status ) {
if ( 'wc-processing' === $key )
$order_statuses['wc-processing'] = _x( 'Order Completed', 'Order status', 'woocommerce' );
}
return $order_statuses;
}

Categories