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