WooCommerce: автоматическое заполнение оплаченных заказов (в зависимости от способов оплаты)

Обычно wooCommerce должен автоматически завершать заказы на виртуальные продукты. Но это не так, и это реальная проблема, даже как ошибка.

Так что на данный момент вы можете найти некоторые полезные вещи (но не очень удобно):

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 Autocomplete Orders

Этот плагин работает для всех способов оплаты, но не для других способов оплаты шлюзами кредитных карт.

Мой вопрос:

Используя (в качестве основы) фрагмент wooCommerce в пункте 1:

Как я могу реализовать условный код на основе методов оплаты woocommerce?

Я имею в виду что-то вроде: если методы оплаты не "BACS", "Оплата при доставке" и "Чек", тогда примените код фрагмента (обновите статус до "выполнено" для оплаченных заказов, касающихся виртуальных продуктов).

Я не мега-эксперт WooCommerce, поэтому я пока не нашел, как настроить методы оплаты в заказах WooCommerce.

Некоторая помощь будет очень приятной.

Благодарю.

5 ответов

Решение

Я нашел решение этой проблемы (работает с WC 3+):

/**
 * 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;
    } 
    // "completed" updated status for paid Orders with all others payment methods
    else {
        $order->update_status( 'completed' );
    }
}

Код помещается в файл function.php активной дочерней темы (или активной темы).

С помощью этого поста: Как проверить способ оплаты заказа WooCommerce по id?

с этим: get_post_meta( $order_id, '_payment_method', true ); от helgatheviking

Банковский перевод, Оплата наложенным платежом и способы оплаты чека игнорируются и сохраняют свой первоначальный статус заказа.

Обновлен код для совместимости с WC 3.0+ (2017-06-10)


Улучшенная версия для WooCommerce 3+ (2018)

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;
    // Updated status to "completed" for paid Orders with all others payment methods
    } else {
        $order->update_status( 'completed' );
    }
}

Код помещается в файл function.php активной дочерней темы (или активной темы).

Для меня этот хук вызывался, даже если платеж не прошел или не прошел, и этот результат для завершения неудавшихся платежей, после некоторого исследования я изменил его, чтобы использовать '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' );
    }
}

Для меня самый простой способ изменения статуса заказа после завершения платежа - это woocommerce_order_item_needs_processing, поскольку этот фильтр предназначен для изменения состояния целевого заказа после завершения платежа.

Вот так будет выглядеть финальный фрагмент:

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

Он также совместим с другими плагинами на сайтах.

Для меня в тестовой системе с песочницей PayPal (плагин WooCommerce PayPal Payments) решение LoicTheAztec (обновление 2019 г.) работало только тогда, когда я добавил $order->update_status( 'completed' );кодовая строка. В return 'completed';в моем случае не влияет, я оставил его только потому, что это фильтр.

      add_filter( 'woocommerce_payment_complete_order_status', function( $status, $order_id, $order ) {
    $order->update_status( 'completed' );
    return 'completed';
}, 10, 3 );

Если вы ищете автозаполнение виртуальных заказов (например, курсы, электронные книги, загружаемые файлы и т. Д.), Это может быть полезно.

 * 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

Другие вопросы по тегам