WooCommerce:自动完成付费订单

时间:2016-02-28 18:45:48

标签: php wordpress woocommerce payment-gateway orders

通常,wooCommerce应自动完成虚拟产品的订单。但它并没有,这是一个真正的问题,甚至像一个BUG。

所以在这一点上你可以找到有用的东西(但不是很方便):

  

1)代码段(您可以在wooCommerce文档中找到):

/**
 * Auto Complete all WooCommerce orders.
 */
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order( $order_id ) {
    if ( ! $order_id ) {
        return;
    }

    $order = wc_get_order( $order_id );
    $order->update_status( 'completed' );
}
     

但此代码段不适用于 BACS * 付款检查付款方式。 Paypal和信用卡网关支付方式可以。

* BACS 是直接银行转帐付款方式

而且......

  

2)插件:WooCommerce自动填充订单

     

此插件适用于所有付款方式,但不适用于其他信用卡网关付款方式

我的问题:

在第1点使用(作为基础)wooCommerce片段:

如何根据woocommerce付款方式实施条件代码?

我的意思是:如果付款方式不是" BACS","付款时付款"和"检查"然后应用代码段(更新状态为"已完成"有关虚拟产品的付费订单)。

一些帮助会非常好。

4 个答案:

答案 0 :(得分:30)

最准确,最有效,最轻量级的解决方案 (适用于WooCommerce 3及以上版本) - 2019

此过滤器挂钩位于:

正如您所看到的,默认情况下,允许的付费订单状态是"处理"并且"已完成"。

  

说明:

     
      
  1. 轻量且有效:

         

    由于它是一个过滤器挂钩,woocommerce_payment_complete_order_status 仅在需要在线付款时触发 (不适用于"检查"," bacs"或" cod"付款方式)。在这里,我们只更改允许的付费订单状态

         

    因此无需为支付网关或其他任何内容添加条件。

  2.   
  3. 准确 (避免多次通知)

         

    这是避免同时发送2个不同客户通知的唯一方法
      •一个用于"处理"订单状态
      •一个用于"完成"订单状态。

         

    因此,只有在完成"完成后才会通知客户#34;订单状态。

  4.   

使用以下代码,只需更改付款订单状态 (由支付订单的付款网关设置)即可完成"已完成" :

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
    return 'completed';
}

代码进入活动子主题(或活动主题)的function.php文件。

相关: WooCommerce: autocomplete paid orders based on shipping method

2018 - 改进版 (适用于WooCommerce 3及以上版本)

基于Woocommerce官方钩子,我找到了解决这个问题的方法*(适用于WC 3 +)。

在Woocommerce中,除了bacs (银行电汇)chequecod (货到付款)之外的所有其他付款网关付费订单状态为"处理"并且"已完成"

所以我的目标是"处理"所有支付网关的订单状态,如Paypal或信用卡付款,更新订单状态以完成。

代码:

add_action( 'woocommerce_thankyou', 'wc_auto_complete_paid_order', 20, 1 );
function wc_auto_complete_paid_order( $order_id ) {
    if ( ! $order_id )
        return;

    // Get an instance of the WC_Product object
    $order = wc_get_order( $order_id );

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    if ( in_array( $order->get_payment_method(), array( 'bacs', 'cod', 'cheque', '' ) ) ) {
        return;
    } 
    // For paid Orders with all others payment methods (paid order status "processing")
    elseif( $order->has_status('processing') ) {
        $order->update_status( 'completed' );
    }
}

代码进入活动子主题(或活动主题)的function.php文件。

原始回答 (适用于所有woocommerce版本)

代码:

/**
 * AUTO COMPLETE PAID ORDERS IN WOOCOMMERCE
 */
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 10, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
    if ( ! $order_id )
    return;

    $order = wc_get_order( $order_id );

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    if ( ( 'bacs' == get_post_meta($order_id, '_payment_method', true) ) || ( 'cod' == get_post_meta($order_id, '_payment_method', true) ) || ( 'cheque' == get_post_meta($order_id, '_payment_method', true) ) ) {
        return;
    } 
    // For paid Orders with all others payment methods (with paid status "processing")
    elseif( $order->get_status()  === 'processing' ) {
        $order->update_status( 'completed' );
    }
}

代码进入活动子主题(或活动主题)的function.php文件。

在这篇文章的帮助下:How to check payment method on a WooCommerce order by id?

使用此get_post_meta( $order_id, '_payment_method', true );来自helgatheviking

银行电汇,货到付款和支票付款方式将被忽略并保持原始订单状态。

更新了与WC 3.0+兼容的代码(2017-06-10)

答案 1 :(得分:0)

如果您正在寻找自动完成的虚拟订单(如课程,电子书,可下载内容等),这可能会有用。

 * Auto Complete all WooCommerce virtual orders.
 * 
 * @param  int  $order_id The order ID to check
 * @return void
 */
function custom_woocommerce_auto_complete_virtual_orders( $order_id ) {

    // if there is no order id, exit
    if ( ! $order_id ) {
        return;
    }

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    if ( in_array( $order->get_payment_method(), array( 'bacs', 'cod', 'cheque', '' ) ) ) {
        return;
    } 

    // get the order and its exit
    $order = wc_get_order( $order_id );
    $items = $order->get_items();

    // if there are no items, exit
    if ( 0 >= count( $items ) ) {
        return;
    }

    // go through each item
    foreach ( $items as $item ) {

        // if it is a variation
        if ( '0' != $item['variation_id'] ) {

            // make a product based upon variation
            $product = new WC_Product( $item['variation_id'] );

        } else {

            // else make a product off of the product id
            $product = new WC_Product( $item['product_id'] );

        }

        // if the product isn't virtual, exit
        if ( ! $product->is_virtual() ) {
            return;
        }
    }

    /*
     * If we made it this far, then all of our items are virual
     * We set the order to completed.
     */
    $order->update_status( 'completed' );
}
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_virtual_orders' );

改编自https://gist.github.com/jessepearson/33f383bb3ea33069822817cfb1da4258

答案 2 :(得分:0)

对我来说,在付款完成后修改订单状态的最简单钩子是“ woocommerce_order_item_needs_processing”,因为此过滤器钩子是在付款完成后修改目标订单状态。

这是最后一个片段的样子:

add_filter('woocommerce_order_item_needs_processing', '__return_false',999);

它还与网站上的其他插件兼容。

答案 3 :(得分:-1)

对我来说,即使付款未通过或未通过也调用了此挂钩,并且此结果完成了失败的付款,经过一些研究,我将其更改为使用“ woocommerce_payment_complete”,因为只有在付款完成并覆盖了付款时才调用@LoicTheAztec上面提到的问题–

add_action( 'woocommerce_payment_complete', 'wc_auto_complete_paid_order', 20, 1 );
function wc_auto_complete_paid_order( $order_id ) {
    if ( ! $order_id )
        return;

    // Get an instance of the WC_Product object
    $order = wc_get_order( $order_id );

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    if ( in_array( $order->get_payment_method(), array( 'bacs', 'cod', 'cheque', '' ) ) ) {
        return;
    // Updated status to "completed" for paid Orders with all others payment methods
    } else {
        $order->update_status( 'completed' );
    }
}