WooCommerce: как настроить отложенную оплату с использованием Polygon и WooCommerce

Диагностика задачи: зачем нужна отложенная оплата в WooCommerce

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

Задача: реализовать механизм отложенной оплаты с использованием платежного шлюза Polygon (https://polygon.io) или аналогичного, который позволяет создавать платежные сессии с возможностью последующего подтверждения.

Как проверить, что отложенная оплата нужна именно вам

  • Покупатели часто бросают корзины на этапе оплаты;
  • Вы хотите контролировать момент списания средств;
  • Необходима интеграция с платежными системами, поддерживающими отложенные платежи;
  • Есть бизнес-процессы, требующие дополнительной валидации перед списанием.

Настройка отложенной оплаты в WooCommerce с Polygon: пошаговое решение

1. Подготовка: требования и подключение к Polygon

Для работы с Polygon нужен API-ключ, который вы получите в личном кабинете сервиса. Убедитесь, что выбран тариф с поддержкой платежных сессий.

Установите плагин WooCommerce и создайте дочернюю тему или плагин для кастомных функций.

2. Создание кастомного платежного метода

Создадим класс платежного метода, который будет инициировать отложенную оплату через Polygon.

if ( ! class_exists( 'WC_Gateway_Polygon_Deferred' ) ) {
    class WC_Gateway_Polygon_Deferred extends WC_Payment_Gateway {
        public function __construct() {
            $this->id = 'polygon_deferred';
            $this->method_title = 'Polygon Отложенная оплата';
            $this->has_fields = false;
            $this->init_form_fields();
            $this->init_settings();

            $this->title = $this->get_option( 'title' );
            $this->description = $this->get_option( 'description' );

            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
        }

        public function init_form_fields() {
            $this->form_fields = array(
                'enabled' => array(
                    'title' => 'Включить/Выключить',
                    'type' => 'checkbox',
                    'label' => 'Включить отложенную оплату через Polygon',
                    'default' => 'yes'
                ),
                'title' => array(
                    'title' => 'Заголовок',
                    'type' => 'text',
                    'default' => 'Оплата позже через Polygon'
                ),
                'description' => array(
                    'title' => 'Описание',
                    'type' => 'textarea',
                    'default' => 'Вы сможете оплатить заказ позже, получив ссылку на оплату.'
                ),
                'api_key' => array(
                    'title' => 'API ключ Polygon',
                    'type' => 'text',
                    'description' => 'Введите ваш API ключ для подключения к Polygon',
                ),
            );
        }

        public function process_payment( $order_id ) {
            $order = wc_get_order( $order_id );
            $api_key = $this->get_option('api_key');

            // Создаем платежную сессию через Polygon API
            $response = $this->create_polygon_payment_session($order, $api_key);
            if ( ! $response || empty($response['payment_url']) ) {
                wc_add_notice('Ошибка создания платежной сессии. Попробуйте позже.', 'error');
                return;
            }

            // Сохраняем ссылку для дальнейшего доступа
            $order->update_meta_data('_polygon_payment_url', $response['payment_url']);
            $order->save();

            // Меняем статус заказа на ожидающий оплату
            $order->update_status('on-hold', 'Ожидает отложенной оплаты через Polygon');

            return array(
                'result'   => 'success',
                'redirect' => $response['payment_url'],
            );
        }

        private function create_polygon_payment_session( $order, $api_key ) {
            $endpoint = 'https://api.polygon.io/v1/payments/create';
            $body = array(
                'amount' => $order->get_total(),
                'currency' => get_woocommerce_currency(),
                'order_id' => $order->get_id(),
                'callback_url' => home_url('/polygon-callback'),
            );

            $args = array(
                'body'        => json_encode($body),
                'headers'     => array(
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $api_key
                ),
                'timeout'     => 20,
                'method'      => 'POST',
            );

            $response = wp_remote_post( $endpoint, $args );
            if ( is_wp_error( $response ) ) {
                return false;
            }

            $data = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( isset($data['payment_url']) ) {
                return $data;
            }

            return false;
        }
    }
}

add_filter( 'woocommerce_payment_gateways', function( $gateways ) {
    $gateways[] = 'WC_Gateway_Polygon_Deferred';
    return $gateways;
});

3. Обработка callback от Polygon для подтверждения оплаты

Создадим endpoint в WordPress для получения уведомлений о статусе оплаты.

add_action( 'init', function () {
    if ( isset($_GET['polygon-callback']) ) {
        $this->handle_polygon_callback();
        exit;
    }
});

function handle_polygon_callback() {
    $order_id = sanitize_text_field( $_GET['order_id'] ?? '' );
    $status = sanitize_text_field( $_GET['status'] ?? '' );

    if ( ! $order_id || ! $status ) {
        status_header(400);
        echo 'Bad Request';
        exit;
    }

    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        status_header(404);
        echo 'Order not found';
        exit;
    }

    if ( $status === 'paid' ) {
        $order->payment_complete();
        $order->add_order_note('Оплата подтверждена Polygon');
    } elseif ( $status === 'failed' ) {
        $order->update_status('failed', 'Оплата через Polygon не прошла');
    }

    status_header(200);
    echo 'OK';
    exit;
}

Проверка результата после внедрения

  • Создайте тестовый заказ и выберите метод оплаты "Polygon Отложенная оплата";
  • Проверьте, что после оформления заказа он получает статус on-hold и сохраняется ссылка _polygon_payment_url в метаданных заказа;
  • Перейдите по ссылке оплаты, имитируйте успешный callback с параметром status=paid и проверьте, что статус заказа меняется на processing или completed;
  • Проверьте логи ошибок и уведомления WooCommerce на предмет сбоев.

Частые ошибки и как их исправить

  • Ошибка 400 или 500 при создании платежной сессии: проверьте правильность API ключа и формат запроса к Polygon.
  • Callback не меняет статус заказа: убедитесь, что endpoint корректно добавлен и доступен без авторизации.
  • Заказ остается в статусе «on-hold» без изменений: возможно, Polygon не отправляет callback — проверьте логи и настройте webhook.
  • Пользователь не видит ссылку на оплату: проверьте, что метод оплаты доступен для выбранной валюты и региона.

Практические советы по безопасности и производительности

  • Храните API ключ Polygon в настройках плагина и не выводите его публично.
  • Обрабатывайте callback с проверкой подписи или IP-адреса для исключения подделок.
  • Используйте transient или кэш для хранения временных данных, чтобы снизить нагрузку на API Polygon.
  • В логах WooCommerce ведите запись ошибок интеграции для быстрого реагирования.

Сравнение вариантов реализации отложенной оплаты

МетодПлюсыМинусы
Плагин WooCommerce с Polygon APIГибкость, контроль над процессом, интеграция с APIТребует разработки и поддержки, знание API
Готовые плагины отложенной оплатыБыстрая настройка, поддержка, документацияМожет не поддерживать Polygon, ограниченная кастомизация
Ручное управление статусами заказовПростота, не требует внешних APIНет автоматизации, возможны ошибки оператора

Наш каталог плагинов WordPress