Если Вы используете плагин Юксассы или другой плагин онлайн-оплаты на сайте, который не подразумевает автоматическую смену статуса. То просто добавьте сниппет-код.
Теперь, если в заказе только виртуальные товары или подписка (плагин Подписка Woocommerce), то статус заказа сразу будет меняеться на Выполнен.
add_action('woocommerce_order_status_processing', function($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
$items = $order->get_items();
$all_virtual_or_subscription = true;
foreach ($items as $item) {
$product = $item->get_product();
if (!$product) {
$all_virtual_or_subscription = false;
break;
}
// Проверка на виртуальный товар
$is_virtual = $product->is_virtual();
// Проверка на подписку (WooCommerce Subscriptions)
$product_type = $product->get_type();
$is_subscription = in_array($product_type, ['subscription', 'variable-subscription']);
if (!($is_virtual || $is_subscription)) {
$all_virtual_or_subscription = false;
break;
}
}
// Если все товары виртуальные или подписки, меняем статус на "completed"
if ($all_virtual_or_subscription) {
$order->update_status('completed', 'Автоматически завершён: все товары — виртуальные или подписки');
}
});Если Вы хотите, чтобы при этом приходило только одно письмо (заказ Выполнен), а письмо заказ в обработке не приходил, то вместо верхнего кода используйте сниппет-код ниже:
function avs_order_only_virtual_or_subscription( $order ) {
if ( ! $order instanceof WC_Order ) {
return false;
}
$items = $order->get_items( 'line_item' );
if ( empty( $items ) ) {
return false;
}
foreach ( $items as $item ) {
$product = $item->get_product();
if ( ! $product ) {
return false;
}
// Виртуальный товар?
$is_virtual = $product->is_virtual();
// Типы подписок из WooCommerce Subscriptions
$type = $product->get_type(); // 'simple', 'variable', 'subscription', 'subscription_variation', 'variable-subscription', ...
$is_subscription = in_array( $type, array( 'subscription', 'subscription_variation', 'variable-subscription' ), true );
if ( ! ( $is_virtual || $is_subscription ) ) {
return false; // встретился физический/иной товар
}
}
return true;
}
/**
* 1) На этапе завершения оплаты сразу ставим статус completed
* вместо processing — тем самым не триггерим письмо "обработка".
*/
add_filter( 'woocommerce_payment_complete_order_status', function( $status, $order_id, $order ) {
if ( $order instanceof WC_Order && avs_order_only_virtual_or_subscription( $order ) ) {
return 'completed';
}
return $status;
}, 10, 3 );
/**
* 2) Доп. защита: если какой-то шлюз/плагин всё-таки инициирует
* письмо "Заказ в обработке", отключаем его для таких заказов.
*/
add_filter( 'woocommerce_email_enabled_customer_processing_order', function( $enabled, $order ) {
if ( $order instanceof WC_Order && avs_order_only_virtual_or_subscription( $order ) ) {
return false; // не отправлять "processing"
}
return $enabled;
}, 10, 2 );