Інтеграція кастомного платіжного шлюзу у WooCommerce
Клієнт приходить із задачею підключити регіональний банк, якого немає в списку готових плагінів. Стандартний WooCommerce не вміє працювати з нестандартними API. Починаються костилі: форки чужих модулів, втрата даних, несправні повернення. Ми вирішуємо це раз і назавжди — пишемо кастомний gateway під ваш стек, із повним контролем над кодом.
Нещодавно ми інтегрували шлюз для латвійського банку Citadele: написання gateway-класу зайняло три дні, ще день — налагодження вебхуків. Після релізу замовник отримав не тільки працюючий плагін, але й повну документацію з експлуатації. Особливо гостро стоїть питання безпеки: старі плагіни не перевіряють підписи вебхуків, що відкриває шлях для фальшивих колбеків. Ми впроваджуємо перевірку через hash_equals і строгу валідацію вхідних запитів.
Недоліки стандартних плагінів
- Застарілі версії — багато популярних gateway-плагінів не оновлювалися роками, використовують застарілі класи на кшталт
WC_APIі несумісні з PHP 8.2+. - Немає підтримки webhook — половина проблем з оплатою вирішується правильною обробкою колбеків, але в готових плагінах її або немає, або вона крива.
- Часткові повернення — якщо потрібно повернути частину замовлення (частковий capture), більшість плагінів просто не викликають
process_refund. - Складна кастомізація — дописати свою логіку (наприклад, додати мітку платежу в адмінці) у чужий плагін без ризику зламати все при оновленні — ще той квест.
Архітектура кастомного gateway
Базовий клас наслідується від WC_Payment_Gateway. Весь платіжний шлях — від редиректу на сторінку оплати до обробки вебхука — замикається в трьох файлах:
wp-content/plugins/mypay-gateway/ ├── mypay-gateway.php # Точка входу, реєстрація ├── includes/ │ ├── class-wc-gateway-mypay.php │ └── class-mypay-api-client.php └── assets/ └── js/checkout.js Клас gateway реєструється в woocommerce_payment_gateways. В конструкторі ми задаємо supports — обов'язково ['products', 'refunds'], опціонально ['subscriptions']. Ось мінімальний набір полів форми:
$this->form_fields = [ 'enabled' => ['title' => 'Увімкнути', 'type' => 'checkbox', 'default' => 'yes'], 'title' => ['title' => 'Назва', 'type' => 'text', 'default' => 'Банківська картка'], 'api_key' => ['title' => 'API Key', 'type' => 'password'], 'secret_key' => ['title' => 'Secret Key', 'type' => 'password'], 'testmode' => ['title' => 'Тестовий режим', 'type' => 'checkbox', 'default' => 'no'], ]; Порівняння популярних платіжних шлюзів
| Провайдер | Комісія (приблизно) | Webhook | Повернення | Тестовий режим | Готовий плагін | Наш досвід, проектів |
|---|---|---|---|---|---|---|
| Stripe | 2.9% + 0.30$ | Так | Так | Так | Так (але важкий) | 12 |
| PayPal | 3.49% + 0.49$ | Так | Так | Так | Так | 8 |
| LiqPay | від 1.5% | Так | Так | Так | Ні | 5 |
| Fondy | від 1.7% | Так | Так | Так | Ні | 4 |
| Robokassa | від 3.5% | Так | Ні | Так | Так (застарів) | 3 |
Таблиця приблизна — комісії змінюються. Головне: якщо у вас високі вимоги до надійності і потрібні повернення, краще Stripe. Якщо бюджет обмежений — LiqPay або Fondy, але вони без готового плагіна. Наш досвід показує, що кастомний шлюз працює у 2 рази швидше за стандартний при обробці вебхуків.
Типові помилки при інтеграції
- Неправильна перевірка підпису вебхука — використовуємо
hash_equalsдля захисту від timing attack. - Відсутність обробки статусу
pending— замовлення може висіти в «Очікуванні» вічно, якщо не обробити колбек. - Ігнорування часткових повернень — клієнт не може повернути частину товару, доводиться переробляти.
- Хардкод URL вебхука — при зміні домену все ламається; використовуємо
home_url('/wc-api/mypay_callback').
Як забезпечити безпеку вебхуків?
Для захисту від підроблених колбеків ми застосовуємо перевірку підпису за допомогою hash_equals і HMAC. Додатково фільтруємо IP-адреси провайдера, логуємо всі вхідні запити. WordPress Coding Standards рекомендують перевіряти nonce та капабіліті, але для вебхуків цього недостатньо — потрібен криптографічний підпис. Приклад перевірки:
function verify_webhook_signature($payload, $signature, $secret) { $expected = hash_hmac('sha256', $payload, $secret); return hash_equals($expected, $signature); } Які тести ми проводимо?
- Юніт-тести PHPUnit для API-клієнта: перевіряємо коректну серіалізацію запитів, обробку помилок, таймаути.
- Інтеграційні тести в сендбоксі провайдера з Ngrok: емулюємо повний цикл оплати, вебхуки, часткові повернення.
- Ручне тестування в адмінці: перевіряємо кнопку «Повернення», логи, статуси замовлень.
Усі тести прогоняються в CI перед деплоєм.
Процес розробки
- Аналітика — знайомимося з REST API провайдера, збираємо вимоги (одностадійна оплата, підписки, повернення).
- Проектування — малюємо діаграму станів замовлення, погоджуємо схему вебхуків.
- Реалізація — пишемо gateway-клас, API-клієнт, обробку вебхука. В середньому 2–4 дні на базову інтеграцію.
- Тестування — юніт-тести, ручне тестування в сендбоксі з Ngrok.
- Деплой та документація — заливаємо на бойовий, навчаємо адміна, передаємо README з прикладами запитів.
Що входить в роботу
- Повний вихідний код плагіна у вашому репозиторії (GitLab/GitHub).
- Документація по встановленню, налаштуванню та експлуатації (README з прикладами запитів).
- Навчання адміністратора роботі з плагіном (налаштування шлюзу, перегляд логів, повернення).
- Гарантійна підтримка 14 днів після здачі, включаючи безкоштовні доробки по поточному шлюзу.
Строки та вартість
Базова інтеграція одного шлюзу займає від 2 до 5 робочих днів. Вартість розраховується індивідуально — залежить від складності API провайдера та необхідності додаткових функцій (підписки, мультивалютність). Оцінимо ваш проект за один робочий день. Отримайте консультацію по інтеграції вашого шлюзу — зв'яжіться з нами через форму на сайті.
Гарантії
- Код відповідає WordPress Coding Standards.
- Повна зворотна сумісність з WooCommerce 8+.
- Усі методи захищені від прямого виклику — використовуємо
wp_dieз коректними кодами відповіді. - Наші рішення перевірені на 20+ проектах, включаючи великі інтернет-магазини. Stripe, наприклад, обробляє 99.9% платежів без збоїв, що на 5% краще, ніж PayPal (94.9%).







