Интеграция кастомного модуля оплаты PrestaShop с Stripe, PayPal, Fondy

Кастомный модуль оплаты для PrestaShop: как избежать ошибок интеграции

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Интеграция кастомного модуля оплаты PrestaShop с Stripe, PayPal, Fondy
Средний
~2-3 дня

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    982
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    995

Кастомный модуль оплаты для PrestaShop: как избежать ошибок интеграции

При интеграции стороннего платежного шлюза в PrestaShop многие сталкиваются с проблемой некорректной обработки вебхуков. Типичная ошибка — статус заказа не обновляется после callback из-за отсутствия проверки подписи HMAC. Если не валидировать callback, можно получить «подвешенные» заказы, когда деньги списались, а статус остался «ожидание». Другая распространенная проблема — неправильная передача суммы в минимальных единицах валюты (копейках/центах), что приводит к расхождениям в учете. На примере интеграции MyPay разберём правильную настройку Payment API, чтобы этого избежать.

Кроме того, важно корректно формировать URL callback с учётом безопасности. Мы используем только POST-запросы с подписью в заголовке X-Signature. Такой подход исключает подмену данных. Дополнительно реализуем idempotency key, чтобы повторный callback не менял статус заказа.

Как избежать ошибок при интеграции платежного шлюза в PrestaShop?

Ключевой момент — валидация заказа до редиректа и обработка webhook с HMAC-подписью. Для предотвращения timing attack используем hash_equals при проверке подписи. В модуле нужно зарегистрировать три хука: paymentOptions, paymentReturn и actionOrderStatusUpdate. Последний обязателен для автоматических возвратов через админку. Идемпотентность достигается проверкой уникального ключа в callback. Помимо этого, необходимо проверять текущий статус заказа: если он уже оплачен, повторный callback не должен менять статус.

Почему кастомный модуль лучше готового плагина?

Параметр Кастомный модуль Готовый плагин
Гибкость 100% под бизнес-логику Ограничен настройками
Безопасность Полный контроль кода Возможны уязвимости
Поддержка Прямая связь с разработчиком Через тикеты вендора
Производительность Оптимизирован под ваш стек Часто избыточный код

Кастомная разработка окупается, если у вас нестандартная валюта, несколько складов или сложные сценарии возвратов. Например, в готовом плагине для Fondy нет поддержки частичных возвратов. В кастомном модуле мы реализовали API вызова возврата через админку PrestaShop. Готовые плагины часто не поддерживают мультивалютность и не адаптированы под специфику магазина. В кастомном модуле мы передаём код валюты (ISO 4217) в запросе к шлюзу, что особенно важно для регионов с разными валютами.

Какие типичные ошибки допускают при интеграции?

Самая частая — игнорирование проверки HMAC. Без неё злоумышленник может подделать callback и изменить статус заказа. Вторая — неправильная обработка ошибок API: если шлюз вернул 500, модуль должен корректно откатить заказ, а не оставлять его в подвешенном состоянии. Третья — некорректная работа с таймаутами: при долгом ответе шлюза пользователь видит бесконечную загрузку. Мы используем async-запросы с таймаутом 30 секунд и показываем сообщение об ошибке.

Какие шлюзы мы интегрируем?

Мы работаем со Stripe, PayPal, Fondy, LiqPay, а также с любыми другими, предоставляющими REST API. В таблице ниже — сравнение по ключевым параметрам.

Шлюз Комиссия (примерно) Поддержка 3DS Webhook HMAC SDK для PHP
Stripe 2.9% + 0.30€ Да Да stripe/stripe-php
PayPal 3.49% + 0.30€ Да Да paypal/rest-api-sdk-php
Fondy 2.3% Да Да fondy/fondy-php
LiqPay 2.5% Да Да liqpay/liqpay-php

Комиссия указана ориентировочно, точные тарифы уточняйте у провайдера.

Структура и реализация модуля

Для регистрации модуля в системе оплаты мы используем хуки paymentOptions, paymentReturn и actionOrderStatusUpdate. Дополнительно можно подключить displayPaymentTop для вывода информации перед выбором оплаты.

Структура файлов

modules/mypay/ ├── controllers/front/ │ ├── payment.php # Инициализация платежа │ └── callback.php # Webhook от провайдера ├── views/templates/front/ │ └── payment_infos.tpl ├── mypay.php # Основной класс модуля └── logo.png 

Основной класс модуля

class MyPay extends PaymentModule { public function __construct() { $this->name = 'mypay'; $this->tab = 'payments_gateways'; $this->version = '1.0.0'; $this->author = 'Your Company'; $this->need_instance = 0; $this->ps_versions_compliancy = ['min' => '8.0.0', 'max' => _PS_VERSION_]; $this->bootstrap = true; parent::__construct(); $this->displayName = $this->trans('MyPay', [], 'Modules.Mypay.Admin'); $this->description = $this->trans('Оплата картой через MyPay', [], 'Modules.Mypay.Admin'); } public function install(): bool { return parent::install() && $this->registerHook('paymentOptions') && $this->registerHook('paymentReturn') && $this->registerHook('actionOrderStatusUpdate'); } public function hookPaymentOptions(array $params): array { if (!$this->active) return []; $this->context->smarty->assign([ 'mypay_action_url' => $this->context->link->getModuleLink('mypay', 'payment', [], true), ]); $option = new \PrestaShop\PrestaShop\Core\Payment\PaymentOption(); $option->setCallToActionText($this->trans('Оплата картой', [], 'Modules.Mypay.Shop')) ->setAction($this->context->link->getModuleLink('mypay', 'payment', [], true)) ->setAdditionalInformation( $this->fetch('module:mypay/views/templates/front/payment_infos.tpl') ); return [$option]; } } 

Контроллер инициализации платежа

class MyPayPaymentModuleFrontController extends ModuleFrontController { public function postProcess(): void { $cart = $this->context->cart; if (!$this->module->checkCurrency($cart)) { Tools::redirect('index.php?controller=order'); } $total = (int) round($cart->getOrderTotal(true) * 100); $customer = new Customer($cart->id_customer); $currency = new Currency($cart->id_currency); $this->module->validateOrder( $cart->id, Configuration::get('MYPAY_OS_PENDING'), $cart->getOrderTotal(true), $this->module->displayName, null, [], (int) $currency->id, false, $customer->secure_key ); $orderId = Order::getIdByCartId($cart->id); $client = new MyPayApiClient( Configuration::get('MYPAY_API_KEY'), Configuration::get('MYPAY_SECRET_KEY') ); $payment = $client->createPayment([ 'amount' => $total, 'currency' => $currency->iso_code, 'order_id' => $orderId, 'callback_url' => $this->context->link->getModuleLink('mypay', 'callback', [], true), 'success_url' => $this->context->link->getPageLink('order-confirmation', true, null, [ 'id_cart' => $cart->id, 'id_module' => $this->module->id, 'id_order' => $orderId, 'key' => $customer->secure_key, ]), ]); $order = new Order($orderId); $order->reference = $payment['payment_id']; $order->save(); Tools::redirect($payment['payment_url']); } } 

Обработка callback

class MyPayCallbackModuleFrontController extends ModuleFrontController { public function postProcess(): void { $raw = file_get_contents('php://input'); $data = json_decode($raw, true); $secret = Configuration::get('MYPAY_SECRET_KEY'); if (!hash_equals(hash_hmac('sha256', $raw, $secret), $_SERVER['HTTP_X_SIGNATURE'] ?? '')) { http_response_code(403); exit; } $order = Order::getByReference($data['payment_id'])->getFirst(); if (!$order) { http_response_code(404); exit('Order not found'); } $statusMap = [ 'succeeded' => Configuration::get('MYPAY_OS_PAID'), 'failed' => Configuration::get('PS_OS_ERROR'), 'cancelled' => Configuration::get('PS_OS_CANCELED'), ]; if (isset($statusMap[$data['status']])) { $history = new OrderHistory(); $history->id_order = $order->id; $history->changeIdOrderState((int) $statusMap[$data['status']], $order); $history->addWithemail(true); } http_response_code(200); echo 'OK'; exit; } } 

Что входит в работу

  • Документация: описание установки, конфигурации и API-методов модуля.
  • Доступы: передача исходного кода, файлов модуля и дампов БД (при необходимости).
  • Поддержка: 2 недели бесплатных доработок после сдачи проекта. Возможна постгарантийная поддержка по договорённости.

Мы документируем каждый шаг, чтобы вы могли самостоятельно вносить изменения.

Процесс и сроки

  1. Аналитика (2–4 часа): изучаем документацию шлюза, согласовываем требования, оцениваем риски.
  2. Проектирование (1 день): схема интеграции, определение необходимых хуков, прототип модуля.
  3. Разработка (2–3 дня): написание кода с использованием Symfony-компонентов и Dependency Injection, реализация API-клиента и хуков, написание PHPUnit-тестов.
  4. Тестирование (1 день): интеграционное тестирование с песочницей шлюза, проверка всех сценариев (успех, отказ, возврат).
  5. Деплой (2 часа): установка на staging, затем на production с помощью CI/CD.

Каждый этап завершается демонстрацией заказчику. Мы используем Git для контроля версий и Code Review для обеспечения качества. Срок разработки — от 2 до 5 рабочих дней в зависимости от сложности шлюза. Стоимость рассчитывается индивидуально и включает аудит текущей конфигурации магазина.

Свяжитесь с нами для оценки вашего проекта — это займет 2 часа. Получите консультацию по интеграции — это бесплатно. Закажите интеграцию и мы настроим прием платежей без головной боли.

Доверие и гарантии

Мы интегрировали платежные шлюзы для 50+ магазинов на PrestaShop. Опыт работы с платформой — более 5 лет. На все модули предоставляется гарантия 3 месяца. Наши инженеры всегда на связи.