Каждый, кто хоть раз пытался прикрутить оплату к своему сайту, знает: это не просто «кнопка и деньги». Это целая история с API, уведомлениями, подписями и кучей подводных камней. Но не переживайте — вместе мы разберемся, как подружить Yii2 с популярными платежными сервисами. Вы узнаете, как это сделать правильно, без боли и лишних нервов.

Digital-студия WNDER

С чего начать: выбираем платежку и готовим почву

Прежде чем писать код, нужно определиться, какая платежная система вам подходит. Я не буду рекламировать конкретных — скажу лишь, что большинство работает по похожему принципу: вы отправляете данные о заказе, получаете ссылку для оплаты или проводите транзакцию напрямую, а затем система присылает уведомление о результате.

Важно сразу понять: у каждой системы есть свои нюансы. Например, одни требуют только HTTPS, другие — определенный формат подписи. Поэтому первый шаг — внимательно изучить документацию. Но чтобы не утонуть в ней, я дам общий алгоритм, который подходит почти всем.

Итак, что нужно подготовить:

  • Доступ к панели управления платежной системы (обычно там вы получаете API-ключи или идентификаторы магазина).
  • Проверочные данные для тестового режима (песочницы).
  • Четкое понимание, какие параметры вы будете передавать: сумма, валюта, описание заказа, ваш внутренний ID.

Кстати, не забудьте про безопасность. Всегда храните секретные ключи в конфигурации, а не прямо в коде. В Yii2 для этого есть отличный механизм — параметры приложения и файл .env.

Структура модуля для работы с платежами

Чтобы не превратить проект в кашу, лучше создать отдельный модуль или компонент. В Yii2 это делается просто. Я предпочитаю выносить всю логику в отдельный класс, например, PaymentService, который будет отвечать за создание платежа, проверку уведомлений и обработку результатов.

Вот пример каркаса такого сервиса:

<?php
namespace app\components;

use Yii;
use yii\base\Component;

class PaymentService extends Component
{
    public $merchantId;
    public $secretKey;
    public $testMode = true;

    public function createPayment($orderId, $amount, $description)
    {
        // Здесь будем формировать запрос к платежной системе
    }

    public function handleCallback($data)
    {
        // Здесь будем проверять подпись и обрабатывать уведомление
    }
}
?>

В конфигурации подключаем этот компонент:

'components' => [
    'payment' => [
        'class' => 'app\components\PaymentService',
        'merchantId' => 'ваш_мерчант_id',
        'secretKey' => 'ваш_секретный_ключ',
        'testMode' => true,
    ],
],

Теперь в любом месте приложения можно вызвать Yii::$app->payment. Удобно, правда?

Отправляем запрос на создание платежа

Допустим, мы работаем с платежной системой, которая принимает POST-запрос и возвращает JSON с ссылкой на оплату. Наш сервис должен сформировать данные, подписать их и отправить.

Обычно подпись — это хеш от сортированных параметров с добавленным секретным ключом. Пример:

public function createPayment($orderId, $amount, $description)
{
    $params = [
        'merchant_id' => $this->merchantId,
        'order_id' => $orderId,
        'amount' => $amount,
        'description' => $description,
        'currency' => 'RUB',
    ];

    $params['signature'] = $this->generateSignature($params);

    // Отправляем запрос через curl или Guzzle
    $response = $this->sendRequest($params);

    return $response['payment_url'];
}

private function generateSignature($params)
{
    ksort($params);
    $data = http_build_query($params) . $this->secretKey;
    return md5($data);
}

Обратите внимание: я сортирую параметры по ключам — это стандартное требование почти всех платежных систем. Если забудете, подпись не совпадет, и система отклонит запрос.

Для отправки запросов я рекомендую использовать библиотеку Guzzle — она удобнее, чем голый curl. Но если вы не хотите подключать лишние зависимости, можно и curl.

Обработка уведомлений от платежной системы

После того как пользователь оплатил, платежная система отправляет на ваш сервер уведомление (обычно на специальный URL). Ваша задача — этот URL принять, проверить подпись и обновить статус заказа.

В Yii2 создаем отдельный контроллер, например, PaymentController с действием actionCallback. Важно: этот экшен должен быть доступен без CSRF-валидации, иначе запрос не пройдет. В Yii2 это делается так:

public function beforeAction($action)
{
    if ($action->id === 'callback') {
        $this->enableCsrfValidation = false;
    }
    return parent::beforeAction($action);
}

А сам экшен выглядит примерно так:

public function actionCallback()
{
    $data = Yii::$app->request->post();

    // Проверяем подпись
    if (!$this->verifySignature($data)) {
        return 'Invalid signature';
    }

    // Обновляем статус заказа в базе
    $order = Order::findOne($data['order_id']);
    if ($order && $order->status === Order::STATUS_NEW) {
        $order->status = Order::STATUS_PAID;
        $order->save();
    }

    return 'OK';
}

Обратите внимание: всегда возвращайте что-то вроде 'OK', чтобы платежная система знала, что уведомление получено. Если вернете ошибку, она будет слать его снова и снова, пока не надоест.

Тестирование и подводные камни

Тестировать интеграцию лучше в песочнице — это специальная среда, где не нужны реальные деньги. Но даже там могут быть сюрпризы. Например, уведомления могут приходить с задержкой или вообще не приходить, если вы используете локальный сервер. Для теста я рекомендую использовать Ngrok — он пробрасывает ваш локальный URL наружу, и платежная система сможет достучаться.

Еще один момент — безопасность. Никогда не доверяйте данным, которые приходят в уведомлении, без проверки подписи. Я видел случаи, когда злоумышленники подделывали запросы и меняли статус заказа, не оплачивая его. Поэтому всегда проверяйте подпись и сумму.

Правило лайфхак: Храните секретный ключ в конфигурации, а не в коде. И никогда не логируйте полные данные платежей — только частично, например, последние 4 цифры карты. Это убережет вас от проблем с законом и клиентами.

Также не забывайте про обработку ошибок. Если платежная система недоступна, ваш сайт не должен падать. Оберните все запросы в try-catch и предусмотрите fallback-сценарий — например, сообщение пользователю, что оплата временно недоступна.

Таблица популярных платежных систем и их особенности

Для наглядности соберу небольшую таблицу с типичными требованиями. Это не реклама, а просто ориентир.

Система Протокол Подпись Тестовый режим
Сбербанк REST API SHA-256 Да
Яндекс.Касса REST API HMAC-SHA256 Да
ЮKassa REST API HMAC-SHA256 Да
PayPal REST API OAuth 2.0 Да

Как видите, общий принцип один, но детали различаются. Поэтому всегда читайте документацию конкретной системы.

Заключение

Интеграция платежной системы в Yii2 — задача не на пять минут, но вполне выполнимая. Главное — не спешить, внимательно читать документацию и тестировать в песочнице. Я показал общий подход, который подойдет для большинства систем. А дальше — дело техники.

Если вы хотите сэкономить время или у вас возникли сложности, всегда можно обратиться к профессионалам. Например, в Digital-студию WNDER, где знают, как сделать все надежно и быстро.

Удачи в ваших проектах!

Студия WNDER