【问题标题】:WooCommerce: Auto complete paid ordersWooCommerce:自动完成已付款订单
【发布时间】:2016-06-11 17:36:54
【问题描述】:

通常,wooCommerce 应该自动完成虚拟产品的订单。但事实并非如此,这是一个真正的问题,甚至是一个 BUG 之类的问题。

所以此时你可以找到一些有用的东西(但不是很方便):

1) 一个 sn-p 代码(您可以在 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' );
}

但此 sn-p 不适用于 BACS*货到付款支票 付款方式。 Paypal 和信用卡网关支付方式都可以。

*BACS 是一种直接银行转账支付方式

还有……

2) 插件: WooCommerce 自动完成订单

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

我的问题:

在第 1 点中使用(作为基础)wooCommerce sn-p:

如何实现基于 woocommerce 支付方式的条件代码?

我的意思是:如果付款方式不是“BACS”、“货到付款”和“支票”,则应用 sn-p 代码(将有关虚拟产品的已付款订单的状态更新为“已完成”)。

一些帮助会非常好。

【问题讨论】:

    标签: php wordpress woocommerce payment-gateway orders


    【解决方案1】:

    最准确、最有效和最轻量级的解决方案 (适用于 WooCommerce 3 及更高版本) - 2019

    此过滤器挂钩位于:

    如您所见,默认情况下允许的已付款订单状态为“处理中”和“已完成”。

    ###解释:

    1. 轻巧高效:

    因为它是一个过滤钩子,woocommerce_payment_complete_order_status 仅在需要在线支付时触发 (不适用于“支票”、“bacs”或“cod”支付方式)。这里我们只是更改允许的已付款订单状态

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

    1. 准确 (避免多次通知)

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

    因此客户只会收到一次关于“已完成”订单状态的通知。

    使用下面的代码,将更改已付款订单状态 (由支付网关为已付款订单设置)为“已完成”:

    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 官方钩子,我找到了解决这个问题的方法 *(Works with 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

    “银行电汇”(bacs)、“货到付款”(cod) 和“支票”(cheque) 付款方式将被忽略并保持其原始订单状态。

    更新代码以兼容 WC 3.0+ (2017-06-10)

    【讨论】:

    • 如我之前所说,别出心裁。
    • 您的解决方案对我的 WooCommerce 问题非常有帮助。
    • @LoicTheAztec 问题是订单将支付,但不会执行操作。明确一点:用户在结帐时离开网站(重定向到贝宝等)进行付款,而不是单击“返回商家”按钮,而是关闭浏览器或转到网站主页或其他任何东西......只要他不访问“谢谢”页面 - 订单就不会完成
    • @LoicTheAztec 这确实是官方的 woocommerce sn-p ......但它有一个警告(如之前的评论所述)。 Paypal 使用 IPN(即时付款通知)将付款批准发送回网站。当它发生时,它会触发“woocommerce_payment_complete”钩子(如果您想自动完成订单,这是正确的钩子)
    • @MotazHomsi 我已经更新了我的答案,以最有效和最轻松的方式,避免在付费订单上向客户发送多个电子邮件通知。
    【解决方案2】:

    对我来说,即使付款未通过或失败,也会调用此钩子,这会导致付款失败。经过一些研究后,我将其更改为使用“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' );
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      这是最终的 sn-p 的样子:

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

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

      【讨论】:

        【解决方案4】:

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

         * 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

        【讨论】:

          猜你喜欢
          • 2018-06-26
          • 2021-01-07
          • 1970-01-01
          • 2020-03-15
          • 2019-09-18
          • 1970-01-01
          • 2019-05-18
          • 2017-10-18
          • 1970-01-01
          相关资源
          最近更新 更多