Плагин активен, настройки сохранены, ошибок нет даже в тестовом режиме — но покупатель не видит способ оплаты на странице оформления. Причина обычно не в плагине, а в типе страницы оформления заказа.
Начиная с WooCommerce 8.3 новые магазины получают блочную страницу оформления заказа, которая выводит способы оплаты в браузере через React. Блочное оформление не показывает автоматически классические шлюзы, унаследованные от WC_Payment_Gateway: каждый способ нужно дополнительно зарегистрировать классом AbstractPaymentMethodType на хуке woocommerce_blocks_payment_method_type_registration и вызовом registerPaymentMethod в JavaScript. Без регистрации ошибки нет — способ просто не отображается. Поскольку тот же плагин работает на классической странице с шорткодом [woocommerce_checkout], проблему легко не заметить.
В разделе WooCommerce → Настройки → Платежи способ оплаты включён. Настройки сохранены, в журнале ошибок пусто. Но на странице оформления заказа видны только банковский перевод или оплата при получении — вашего шлюза нет.
Именно с этим мы столкнулись при проверке интеграции виртуального POS банка QNB для Castor Coffee: в одной мультисайт-установке розничный магазин использовал классическую страницу оформления с шорткодом, а оптовый — блочную. Код плагина был верным, расчёт хеша совпадал с тем, что ожидает банк, — но на оптовом сайте способ оплаты не появился бы никогда, даже после заполнения настроек.
Первый вопрос — не о плагине, а о странице. Посмотрите содержимое страницы оформления заказа:
wp post get $(wp option get woocommerce_checkout_page_id) --field=post_content | head -c 200
<!-- wp:woocommerce/checkout --> — блочное оформление[woocommerce_checkout] — классическое оформлениеВ мультисайте проверяйте каждый сайт отдельно: сайты, созданные в разное время, могут иметь разные типы страницы оформления.
Классическая страница оформления формируется на сервере в PHP: WooCommerce перебирает доступные шлюзы и выводит результат payment_fields() каждого. Блочная страница — это приложение на React, работающее в браузере и получающее данные корзины и заказа через Store API. Чтобы показать способ оплаты, ей нужно описание, зарегистрированное на стороне JavaScript.
WooCommerce не выводит это описание из классического шлюза. Итог: шлюз зарегистрирован на сервере, is_available() возвращает true, а блочная страница о нём ничего не знает.
Сначала пишется класс, который представляет шлюз блочной стороне. Значение $name должно в точности совпадать с id шлюза:
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
final class My_Gateway_Blocks extends AbstractPaymentMethodType {
protected $name = 'my_gateway'; // то же, что WC_Payment_Gateway::$id
public function initialize() {
$this->settings = get_option( 'woocommerce_my_gateway_settings', array() );
}
public function is_active() {
$gateways = WC()->payment_gateways()->payment_gateways();
return isset( $gateways[ $this->name ] ) && $gateways[ $this->name ]->is_available();
}
public function get_payment_method_script_handles() {
wp_register_script( 'my-gateway-blocks', plugins_url( 'assets/blocks.js', __FILE__ ),
array( 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-html-entities' ), '1.0', true );
return array( 'my-gateway-blocks' );
}
public function get_payment_method_data() {
return array( 'title' => 'Банковская карта', 'supports' => array( 'products' ) );
}
}
add_action( 'woocommerce_blocks_payment_method_type_registration', function ( $registry ) {
$registry->register( new My_Gateway_Blocks() );
} );
Важно использовать внутри is_active() собственное решение шлюза is_available(): при отсутствии учётных данных или неподдерживаемой валюте способ скрыт и на блочной странице, и оба типа оформления подчиняются одному правилу.
Также объявите совместимость с блоками в главном файле плагина, иначе редактор может пометить плагин как несовместимый:
add_action( 'before_woocommerce_init', function () {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );
} );
Данные из get_payment_method_data() доступны в браузере по ключу <name>_data. Минимальная регистрация без сборки:
( function () {
var settings = window.wc.wcSettings.getSetting( 'my_gateway_data', {} );
var el = window.wp.element.createElement;
var label = settings.title || 'Банковская карта';
window.wc.wcBlocksRegistry.registerPaymentMethod( {
name: 'my_gateway', // то же, что $name в PHP
label: el( 'span', null, label ),
ariaLabel: label,
content: el( 'p', null, 'Вы будете перенаправлены на защищённую страницу оплаты.' ),
edit: el( 'p', null, 'Вы будете перенаправлены на защищённую страницу оплаты.' ),
canMakePayment: function () { return true; },
supports: { features: settings.supports || [ 'products' ] }
} );
} )();
Шлюзам, которые перенаправляют покупателя на страницу 3D Secure банка, больше ничего не нужно: когда process_payment() возвращает адрес redirect, блочная страница отправляет покупателя туда. Шлюзам, принимающим данные карты на вашей странице, дополнительно нужно событие onPaymentSetup, чтобы передать платёжные данные в Store API.
Если после регистрации способ всё ещё не виден, проверьте по порядку. Ни одна из причин не выдаёт видимой ошибки:
id шлюза, $name в PHP и name в JavaScript должны совпадатьwc.wcBlocksRegistry или не выполняется вовсе — исключите страницу оформления из оптимизацииwc-blocks-registry в списке зависимостей в консоли появится wc is not definedis_active() возвращает false: незаполненные настройки, неподдерживаемая валюта или ошибка в условииРегистрацию на стороне сервера можно проверить через WP-CLI:
wp eval '
$r = Automattic\WooCommerce\Blocks\Package::container()
->get( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry::class );
do_action( "woocommerce_blocks_payment_method_type_registration", $r );
echo implode( ", ", array_keys( $r->get_all_registered() ) );'
Если имени вашего способа нет в списке, проблема в регистрации PHP. Если оно есть, но способ не виден, проверьте в браузере загрузку скрипта и ошибки в консоли, а затем — решение is_active().
Блочное оформление заказа — отдельная дверь для классических платёжных шлюзов, и открывается она только регистрацией. Диагностика начинается с одной команды: страница оформления блочная или с шорткодом? Если блочная — напишите для шлюза класс AbstractPaymentMethodType и вызов registerPaymentMethod, держите имя одинаковым во всех трёх местах и не откладывайте скрипт. Способ оплаты, который выглядит готовым принимать платежи, но не виден покупателям, — одна из самых дорогих ошибок: никто не жалуется, продажи просто не происходят.
wp:woocommerce/checkout — блочное, [woocommerce_checkout] — классическоеAbstractPaymentMethodType + woocommerce_blocks_payment_method_type_registrationwc.wcBlocksRegistry.registerPaymentMethod()id шлюза = $name в PHP = name в JSwc-blocks-registry, wc-settings, wp-elementdeclare_compatibility( 'cart_checkout_blocks', … )Чаще всего потому, что страница оформления блочная. С WooCommerce 8.3 новые магазины получают блочное оформление, которое не показывает классические платёжные шлюзы автоматически. Шлюз нужно дополнительно зарегистрировать классом AbstractPaymentMethodType и вызовом registerPaymentMethod в JavaScript.
Да: если преобразовать блок оформления в классическую версию с шорткодом, способ сразу появится. Но это не окончательное решение — новые возможности WooCommerce выходят именно для блочного оформления. Сделать плагин совместимым с блоками — разовая работа.
Проверьте, что имя совпадает во всех трёх местах: id шлюза, $name в классе PHP и name в JavaScript. Затем проверьте, не откладывает ли скрипт плагин ускорения и возвращает ли is_active() значение true. Ни одна из этих причин не выдаёт видимой ошибки.
Нет. Когда process_payment() возвращает адрес redirect, блочная страница оформления перенаправляет покупателя. Дополнительный код нужен только шлюзам, принимающим данные карты на вашей странице.