Інтеграція платіжних шлюзів PrestaShop

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Інтеграція платіжних шлюзів PrestaShop
Середня
~2-3 робочих дні
Часті питання

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

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Інтеграція платіжних шлюзів PrestaShop

PrestaShop 8.x використовує оновлений Payment API порівняно з 1.7.x — основні класи такі ж, але з'явився PaymentOption з підтримкою iframe. Кастомний модуль оплати реєструється через хуки та реалізує кілька обов'язкових методів. Строк розробки — 2–4 робочих дні.

Структура модуля

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];
    }
}

Контролер ініціалізації платежу

// controllers/front/payment.php
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

// controllers/front/callback.php
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;
    }
}

Повернення через admin

PrestaShop не викликає модуль автоматично при поверненні — потрібно підписатися на хук actionOrderStatusUpdate:

public function hookActionOrderStatusUpdate(array $params): void
{
    $newStatus  = $params['newOrderStatus'];
    $order      = $params['order'];

    if ($newStatus->id !== (int) Configuration::get('PS_OS_REFUND')) {
        return;
    }

    $client = new MyPayApiClient(
        Configuration::get('MYPAY_API_KEY'),
        Configuration::get('MYPAY_SECRET_KEY')
    );

    $client->refund($order->reference, (int) round($order->total_paid * 100));
}

Налаштування в admin

Сторінка конфігурації модуля (getContent()) використовує HelperForm для рендерингу форми з полями API-ключів, тестового режиму, маппінгу статусів замовлення. Статуси замовлення (Pending, Paid, Failed) створюються при установці модуля та зберігаються у таблиці ps_order_state.