Что такое отложенный платеж и зачем он нужен в WooCommerce
Отложенный платеж — это возможность оформить заказ с последующей оплатой через определённое время или по согласованию. Такая схема востребована для корпоративных клиентов, оптовиков или в условиях, когда нужен дополнительный контроль перед оплатой.
WooCommerce по умолчанию не поддерживает отложенные платежи как отдельный функционал. Зачастую пользователи ставят плагины, но это увеличивает нагрузку и может конфликтовать с другими решениями. В этой статье рассмотрим, как реализовать отложенный платеж с помощью кода с минимумом изменений.
Диагностика: как понять, что вам нужен именно отложенный платеж
- Клиенты хотят оформлять заказ без мгновенной оплаты.
- Нужно вручную проверять и подтверждать платежи.
- Вам не подходит стандартный статус
on-holdили его нужно расширить функционально. - Отказ от сторонних плагинов ради лёгкости поддержки.
Если вы видите, что клиентам нужны опции оплаты позже без блокировки заказа, то пора переходить к реализации.
Пошаговое решение: добавляем статус заказа и логику отложенного платежа
1. Регистрируем новый статус заказа
Добавим статус deferred-payment, который обозначит отложенный платеж.
add_action('init', function() {
register_post_status('wc-deferred-payment', [
'label' => 'Отложенный платеж',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop('Отложенный платеж <span class="count">(%s)</span>', 'Отложенных платежей <span class="count">(%s)</span>')
]);
});2. Добавляем статус в список статусов WooCommerce
add_filter('wc_order_statuses', function($order_statuses) {
$new_statuses = [];
foreach ($order_statuses as $key => $status) {
$new_statuses[$key] = $status;
if ('wc-on-hold' === $key) {
$new_statuses['wc-deferred-payment'] = 'Отложенный платеж';
}
}
return $new_statuses;
});3. Добавляем кнопку в админке для смены статуса на отложенный платеж
Чтобы не менять статус вручную через выпадающий список, добавим быстрый переход:
add_action('woocommerce_admin_order_actions_end', function($order) {
if ($order->has_status('pending') || $order->has_status('on-hold')) {
$url = wp_nonce_url(admin_url('admin-ajax.php?action=set_deferred_payment&order_id=' . $order->get_id()), 'set_deferred_payment_' . $order->get_id());
echo '<a href="' . esc_url($url) . '" class="button tips" data-tip="Отложить оплату" style="margin-left:5px;">Отложить оплату</a>';
}
});
add_action('wp_ajax_set_deferred_payment', function() {
$order_id = intval($_GET['order_id'] ?? 0);
if (!$order_id || !current_user_can('edit_shop_orders')) {
wp_die('Недостаточно прав');
}
check_admin_referer('set_deferred_payment_' . $order_id);
$order = wc_get_order($order_id);
if ($order) {
$order->update_status('deferred-payment', 'Статус изменён на отложенный платеж через админку');
}
wp_redirect(wp_get_referer() ?: admin_url('edit.php?post_type=shop_order'));
exit;
});4. Обработка логики фронтенда: запретить оплату сразу, но разрешить оформление
Чтобы покупатель мог оформить заказ с выбором отложенного платежа, добавим метод оплаты «Оплата позже».
add_filter('woocommerce_payment_gateways', function($gateways) {
class WC_Gateway_Deferred_Payment extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'deferred_payment';
$this->method_title = 'Оплата позже';
$this->enabled = 'yes';
$this->title = 'Оплата позже';
$this->description = 'Оформление заказа с последующей оплатой.';
}
public function process_payment($order_id) {
$order = wc_get_order($order_id);
$order->update_status('deferred-payment', 'Пользователь выбрал отложенный платеж.');
wc_reduce_stock_levels($order_id);
WC()->cart->empty_cart();
return [
'result' => 'success',
'redirect' => $this->get_return_url($order),
];
}
}
$gateways['deferred_payment'] = 'WC_Gateway_Deferred_Payment';
return $gateways;
});Проверка результата после внедрения
- В админке WooCommerce появился новый статус «Отложенный платеж».
- В списке заказов можно быстро сменить статус на отложенный платеж с кнопки.
- На фронтенде в способах оплаты появился пункт «Оплата позже».
- При выборе этого способа заказ создаётся со статусом
deferred-payment, товар резервируется, но оплата не требуется сразу. - Заказ виден в админке со статусом «Отложенный платеж». Можно вручную подтвердить оплату или отменить заказ.
Для проверки выполните тестовый заказ с новым методом оплаты и убедитесь, что заказ появляется в списке с нужным статусом и что в админке работает кнопка смены статуса.
Частые ошибки и как их исправить
- Статус не отображается в списке заказов. Проверьте, что хук
wc_order_statusesвозвращает массив с новым статусом и что статус зарегистрирован черезregister_post_status. - Кнопка «Отложить оплату» не появляется. Убедитесь, что пользователь имеет права
edit_shop_ordersи что код вwoocommerce_admin_order_actions_endдобавлен корректно. - При выборе «Оплата позже» заказ остаётся в статусе «ожидает оплаты». Проверьте, что класс метода оплаты зарегистрирован и метод
process_paymentобновляет статус. - Товары не резервируются или не уменьшается запас. В методе оплаты должен вызываться
wc_reduce_stock_levels($order_id).
Практические советы по безопасности и производительности
- Для безопасности используйте
check_admin_refererдля nonce-проверки при смене статуса из админки. - Минимизируйте добавление новых хуков и функций, чтобы не перегружать сайт.
- Если нужно массово менять статусы, пишите отдельные скрипты с WP CLI.
- Регулярно очищайте заказы со статусом
deferred-payment, которые не были оплачены после определённого срока, чтобы не засорять базу.
Сравнение вариантов реализации отложенного платежа
| Вариант | Плюсы | Минусы |
|---|---|---|
| Плагин отложенного платежа | Быстрая установка, готовый функционал | Лишние зависимости, возможные конфликты, нагрузка |
| Кодовое решение (описанное выше) | Контроль, лёгкость, минимальная нагрузка | Требует навыков, нужно тестировать и поддерживать |
| Использование статуса on-hold с дополнительными заметками | Простая реализация, без кода | Нет явного разделения, неудобно для пользователей и админов |