Криптоплатежи на WordPress
Как принимать криптоплатежи на WordPress и WooCommerce без готового плагина: два куска кода, куда их поставить и что чаще всего ломается.

В WordPress нет встроенного способа принимать крипту, а готового плагина Qvard для WordPress пока нет. Зато есть простой API, а WordPress отлично умеет с ним работать. В материале показано, как подключить магазин на WooCommerce к Qvard двумя небольшими кусками кода и что проверить, если не заработало.
Плагин или свой код: честный выбор
На WordPress первым делом ищут плагин, и это разумно: поставил, вставил ключ, готово. Вот как обстоят дела сейчас.
- Плагина Qvard для WordPress или WooCommerce пока нет. Интеграция идёт через API. Лучше сказать об этом прямо, чем отправлять вас искать несуществующий плагин.
- Сторонние плагины других криптошлюзов к Qvard не подключатся. Каждый плагин работает с API своего шлюза.
- Свой вариант небольшой. Один запрос создаёт платёж, одна точка принимает результат. WordPress-разработчик напишет это за час-два, и вы полностью контролируете, что происходит с заказом.
Если нужна настройка без кода, Qvard к этому пока не готов. Если есть разработчик или час его времени, читайте дальше.
Как устроена интеграция
Схема для заказа в WooCommerce:
- На оформлении покупатель выбирает «Оплатить криптой». Ваш код создаёт платёж через API Qvard, используя номер заказа WooCommerce как
idплатежа. - Qvard возвращает
redirectUrl. Вы отправляете клиента на эту страницу, где он выбирает актив и сеть и платит из своего кошелька. - Когда платёж завершён, Qvard обращается к точке на вашем сайте.
- Точка находит заказ по
idи помечает его оплаченным, после чего WooCommerce отправляет обычные письма и переводит заказ в обработку.
Сайт на WordPress не генерирует адреса и не следит за блокчейном. Вы пишете два куска: запрос, создающий платёж, и точку, принимающую результат.
Кусок 1: создать платёж
В WordPress вызовите wp_remote_post на https://api.qvard.com/api/v1/payment с ключом в заголовке Authorization: Bearer и JSON: id (номер заказа строкой) и price (сумма в долларах США). Успешный ответ: HTTP 201 и redirectUrl.
Пример ниже делает именно это для заказа WooCommerce. Храните ключ в wp-config.php как константу, а не в теме и не в опциях базы, откуда его могут вытащить плагины и выгрузки.
Две детали WooCommerce:
- Валюта. Цена отправляется в долларах США. Если магазин работает в другой валюте, переведите сумму заказа в доллары до запроса, иначе клиент увидит неверную сумму.
- Повторы. Тот же
idдля того же способа оплаты возвращает уже созданный платёж, поэтому двойной клик или повторный запрос не создадут второй.
Подключите это в собственный способ оплаты или в шаг оформления, который обрабатывает выбор «Оплатить криптой», и перенаправьте клиента на полученный адрес.
<?php
// Create a Qvard payment for a WooCommerce order and return the page to send the customer to.
// QVARD_API_KEY is defined in wp-config.php, never in a theme or a public repository.
function qvard_create_payment( WC_Order $order ) {
$response = wp_remote_post( 'https://api.qvard.com/api/v1/payment', array(
'timeout' => 15,
'headers' => array(
'Authorization' => 'Bearer ' . QVARD_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'id' => (string) $order->get_id(), // matched again in the webhook
'price' => (float) $order->get_total(), // US dollars
) ),
) );
if ( is_wp_error( $response ) || 201 !== wp_remote_retrieve_response_code( $response ) ) {
return null;
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
return isset( $data['redirectUrl'] ) ? $data['redirectUrl'] : null;
}Кусок 2: принять webhook
Зарегистрируйте REST-маршрут в WordPress и сохраните его адрес в проекте Qvard как callback URL, например https://your-site.com/wp-json/qvard/v1/webhook. Когда платёж завершён, Qvard отправляет POST с id, который вы передали, и status платежа, с подписью в заголовке X-Qvard-Signature.
Три правила для точки:
- Проверяйте подпись. Проверьте
X-Qvard-Signature(HMAC-SHA256 вашим секретным ключом) через SDK и отклоняйте всё, что не совпадает. - Помечайте заказ оплаченным только по completed. Клиент, вернувшийся на сайт, не доказательство оплаты, а статус
partialзначит, что отправлено меньше нужного. - Отвечайте ровно HTTP 200. Любой другой статус Qvard считает ошибкой и повторяет (пять попыток примерно за шесть минут), а редиректы не обрабатывает. Из-за повторов обработчик должен быть безопасным при повторном запуске;
is_paid()в примере исключает двойное завершение.
О безопасности подробнее в материале как защитить webhook криптоплатежей.
<?php
// Webhook endpoint: https://your-site.com/wp-json/qvard/v1/webhook
add_action( 'rest_api_init', function () {
register_rest_route( 'qvard/v1', '/webhook', array(
'methods' => 'POST',
'permission_callback' => '__return_true', // authenticated below by the X-Qvard-Signature header
'callback' => function ( WP_REST_Request $request ) {
try {
$payload = ( new Qvard\Qvard( QVARD_API_KEY ) )->webhooks->constructEvent( $request->get_body(), $request->get_header( 'x-qvard-signature' ), QVARD_API_KEY );
} catch ( \Exception $e ) {
return new WP_REST_Response( null, 401 );
}
$order = wc_get_order( (int) ( $payload['id'] ?? 0 ) );
if ( $order && 'completed' === ( $payload['status'] ?? '' ) && ! $order->is_paid() ) {
$order->payment_complete();
}
return new WP_REST_Response( null, 200 ); // must be exactly 200
},
) );
} );Что чаще всего ломается на WordPress
Большинство неудачных интеграций на WordPress упирается в окружение, а не в код:
- Webhook не приходит. Плагин безопасности, файрвол или страница «скоро открытие» блокирует незнакомые POST-запросы. Разрешите маршрут и проверьте его снаружи вашей сети.
- Маршрут отвечает 404. Выключены «красивые» постоянные ссылки или файл плагина не загружен. Откройте маршрут в браузере: 401 или 405 значит, что он есть, 404 значит, что нет.
- Кэширование страниц. Убедитесь, что плагин кэша и CDN не кэшируют и не переписывают запросы к
/wp-json/. - Заказ оплачивается дважды. Обработчик не идемпотентен. Проверяйте
is_paid()перед завершением. - Неверная сумма. Валюта магазина не доллары США, а конвертации не было.
- Медленные ответы. Тяжёлые плагины на завершении заказа могут задерживать ваш ответ. Возвращайте 200 быстро, а долгую работу делайте после.
После оплаты клиент возвращается на сайт самостоятельно, поскольку возврата по ссылке пока нет. Дайте ему страницу заказа с реальным статусом, а не страницу «спасибо», которая считает оплату успешной.
Проверьте до запуска
Откройте демо-счёт, чтобы увидеть страницу оплаты, которую получит клиент. Затем:
- Создайте платёж из тестового заказа и убедитесь, что приходит
redirectUrl. - Оплатите небольшую настоящую сумму и проверьте, что webhook пришёл и заказ стал оплаченным.
- Один раз заставьте точку вернуть ошибку, проверьте, что Qvard повторяет доставку, а заказ не завершается дважды.
- Выведите небольшую сумму с баланса на кошелёк.
Отдельного sandbox пока нет, поэтому берите небольшие реальные суммы. Эндпоинты и поля описаны в документации для разработчиков, а обзор интеграций показывает, что подключено уже сейчас.
Сколько это стоит в работе
Абонентской платы нет. Комиссия за платёж индивидуальна для вашего проекта и по странице тарифов начинается с 1%, а индивидуально может быть снижена до 0,1%; актуальные условия смотрите на странице тарифов. Вывод на ваш кошелёк стоит только сетевую комиссию. Вывода на банковский счёт в фиате нет.
Единственная статья расходов, которую нужно учесть, это время разработки: немного один раз и немного поддержки, когда WordPress или WooCommerce меняют способ регистрации платёжных методов.
FAQ
Есть ли плагин Qvard для WordPress или WooCommerce?
Пока нет. Сейчас интеграция идёт через API: один запрос создаёт платёж, один webhook принимает результат. WordPress-разработчик добавит оба в магазин за час-два.
Можно ли использовать криптоплагин, сделанный для другого шлюза?
Нет. Каждый плагин работает со своим шлюзом и не подключится к Qvard. Нужен собственный код, который обращается к API Qvard.
Мой магазин работает не в долларах США. Что делать?
Цена передаётся в Qvard в долларах США, поэтому переведите сумму заказа до создания платежа. Клиент заплатит эквивалент в выбранном активе по курсу, зафиксированному на один час.
Webhook не доходит до сайта. Почему?
Обычно запрос блокирует плагин безопасности, файрвол или страница обслуживания, либо REST-маршрут не зарегистрирован. Проверьте, что маршрут отвечает снаружи вашей сети и возвращает ровно HTTP 200 на корректный запрос.
