Last active
June 4, 2024 05:26
-
-
Save willgorham/874c4ac943fc27443cd862a93764d659 to your computer and use it in GitHub Desktop.
WooCommerce: Automatically complete virtual orders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
add_filter( 'woocommerce_payment_complete_order_status', 'wmg_auto_complete_virtual_orders', 10, 3 ); | |
/** | |
* Automatically complete orders with only virtual products | |
* | |
* @param string $payment_complete_status Order status used after an order payment is received | |
* @param int $order_id ID of the order being processed | |
* @param WC_Order $order Order object being processed | |
* @return string $payment_complete_status Updated order status | |
*/ | |
function wmg_auto_complete_virtual_orders( $payment_complete_status, $order_id, $order ) { | |
$current_status = $order->get_status(); | |
// We only want to update the status to 'completed' if it's coming from one of the following statuses: | |
$allowed_current_statuses = array( 'on-hold', 'pending', 'failed' ); | |
if ( 'processing' === $payment_complete_status && in_array( $current_status, $allowed_current_statuses ) ) { | |
$order_items = $order->get_items(); | |
// Create an array of products in the order | |
$order_products = array_filter( array_map( function( $item ) { | |
// Get associated product for each line item | |
return $item->get_product(); | |
}, $order_items ), function( $product ) { | |
// Remove non-products | |
return !! $product; | |
} ); | |
if ( count( $order_products ) > 0 ) { | |
// Check if each product is 'virtual' | |
$is_virtual_order = array_reduce( $order_products, function( $virtual_order_so_far, $product ) { | |
return $virtual_order_so_far && $product->is_virtual(); | |
}, true ); | |
if ( $is_virtual_order ) { | |
$payment_complete_status = 'completed'; | |
} | |
} | |
} | |
return $payment_complete_status; | |
} |
@colinskuse Your theme's functions.php
file. Ideally, you should be using a Child Theme. You can find the functions.php
file at wp-content/themes/your-theme
.
If there's code there already, just paste the code at the very bottom or the very top. Make sure you remove the starting <?php
tag in this script if there's already one in your file, though.
Any suggestions for the error thrown below. This was working until some recent updates.
2023-06-16T01:25:05+00:00 CRITICAL Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, bool given in /home/runcloud/webapps/bastore/wp-content/themes/oceanwp-child-theme-master/functions.php:192
Stack trace:
#0 /home/runcloud/webapps/bastore/wp-includes/class-wp-hook.php(308): auto_complete_virtual_orders()
#1 /home/runcloud/webapps/bastore/wp-includes/plugin.php(205): WP_Hook->apply_filters()
#2 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce/includes/class-wc-order.php(142): apply_filters()
#3 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce-square/includes/Framework/PaymentGateway/Payment_Gateway_Direct.php(329): WC_Order->payment_complete()
#4 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce/includes/class-wc-checkout.php(1050): WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Direct->process_payment()
#5 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce/includes/class-wc-checkout.php(1279): WC_Checkout->process_order_payment()
#6 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce/includes/class-wc-ajax.php(485): WC_Checkout->process_checkout()
#7 /home/runcloud/webapps/bastore/wp-includes/class-wp-hook.php(308): WC_AJAX::checkout()
#8 /home/runcloud/webapps/bastore/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#9 /home/runcloud/webapps/bastore/wp-includes/plugin.php(517): WP_Hook->do_action()
#10 /home/runcloud/webapps/bastore/wp-content/plugins/woocommerce/includes/class-wc-ajax.php(96): do_action()
#11 /home/runcloud/webapps/bastore/wp-includes/class-wp-hook.php(308): WC_AJAX::do_wc_ajax()
#12 /home/runcloud/webapps/bastore/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#13 /home/runcloud/webapps/bastore/wp-includes/plugin.php(517): WP_Hook->do_action()
#14 /home/runcloud/webapps/bastore/wp-includes/template-loader.php(13): do_action()
#15 /home/runcloud/webapps/bastore/wp-blog-header.php(19): require_once('...')
#16 /home/runcloud/webapps/bastore/index.php(17): require('...')
#17 {main}
thrown in /home/runcloud/webapps/bastore/wp-content/themes/oceanwp-child-theme-master/functions.php on line 192
The line:
if ( count( $order_products > 0 ) ) {
Needs to be changed to:
if ( count( $order_products ) > 0 ) {
Note the correct placement of the close bracket on the count() function - this fixes the error you are all encountering
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
im a bit of a newbe to code, Wordpress & WooCommerce. where do i need to place this code ?