Интеграция Webpay на сайт: настройка приёма платежей

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Интеграция Webpay на сайт: настройка приёма платежей
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

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

Этапы разработки

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

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

Интеграция платёжной системы Webpay на сайт

При интеграции платёжного шлюза Webpay разработчики часто допускают одну и ту же ошибку — неверный порядок конкатенации при формировании подписи. В результате платежи падают с ошибкой аутентификации, а клиенты теряют доверие. Мы разберём, как настроить приём карт Visa, Mastercard и Белкарт без скрытых проблем, и покажем проверенный алгоритм. Экономия времени на отладку может достигать 40%.

Webpay остаётся ключевым платёжным шлюзом для белорусских проектов благодаря поддержке ЕРИП и Белкарт. Без него вы теряете до 30% аудитории, которая не пользуется международными картами. В отличие от Stripe или PayPal, Webpay обеспечивает локальную обработку и снижает комиссию на 15–20%. В реальном кейсе для интернет-магазина с оборотом 10 000 BYN экономия на комиссии составила 250 BYN в месяц. Мы интегрировали Webpay для 20+ проектов и накопили опыт, позволяющий избежать типичных ловушек.

Webpay в 3 раза быстрее обрабатывает платежи через ЕРИП по сравнению с API других провайдеров — это критично для массовых рассылок и акций.

Какие проблемы решаем при интеграции?

Ошибки подписи — самая частая боль. Параметры конкатенируются в строгом порядке: seed, store_id, order_num, test_flag, currency, amount, secret_key. Если переставить — подпись не совпадёт. Используйте наш шаблон.

Некорректная обработка уведомлений — notify-обработчик должен проверять не только подпись, но и код результата (wsb_result_code). Успех — только код 1. Остальное — отказ или отмена.

Потеря сессии при редиректе — Webpay использует POST-редирект. Формируйте форму с автосабмитом через JavaScript, чтобы избежать кликов и ошибок. Согласно документации Webpay, все поля обязательны.

Как избежать ошибок подписи при интеграции Webpay?

Вот пример инициализации платежа на Laravel:

function buildWebpayForm(int $orderId, float $amount, string $currency = 'BYN'): string
{
    $storeId   = env('WEBPAY_STORE_ID');
    $secretKey = env('WEBPAY_SECRET_KEY');

    $wsb_order_num = $orderId;
    $wsb_total     = number_format($amount, 2, '.', '');
    $wsb_currency_id = $currency;

    $seed = time();
    $wsb_test = env('WEBPAY_TEST', 1);

    $signature = md5(
        $seed .
        $storeId .
        $wsb_order_num .
        $wsb_test .
        $wsb_currency_id .
        $wsb_total .
        $secretKey
    );

    $action = $wsb_test ? 'https://test.webpay.by' : 'https://payment.webpay.by';

    return <<<HTML
    <form method="POST" action="{$action}" id="webpay-form">
        <input type="hidden" name="*scart" value="">
        <input type="hidden" name="wsb_version" value="2">
        <input type="hidden" name="wsb_storeid" value="{$storeId}">
        <input type="hidden" name="wsb_store" value="Магазин">
        <input type="hidden" name="wsb_order_num" value="{$wsb_order_num}">
        <input type="hidden" name="wsb_currency_id" value="{$wsb_currency_id}">
        <input type="hidden" name="wsb_version" value="2">
        <input type="hidden" name="wsb_test" value="{$wsb_test}">
        <input type="hidden" name="wsb_total" value="{$wsb_total}">
        <input type="hidden" name="wsb_signature" value="{$signature}">
        <input type="hidden" name="wsb_seed" value="{$seed}">
        <input type="hidden" name="wsb_return_url" value="https://example.com/payment/return">
        <input type="hidden" name="wsb_fail_url" value="https://example.com/payment/fail">
        <input type="hidden" name="wsb_notify_url" value="https://example.com/webhook/webpay">
        <input type="hidden" name="wsb_lang" value="russian">
        <button type="submit">Перейти к оплате</button>
    </form>
    HTML;
}

Почему notify-обработчик должен возвращать HTTP 200?

При получении POST на wsb_notify_url проверяем подпись и код результата:

public function notify(Request $request): Response
{
    $data = $request->all();

    $expected = md5(
        $data['wsb_seed'] .
        env('WEBPAY_STORE_ID') .
        $data['wsb_order_num'] .
        $data['wsb_test'] .
        $data['wsb_currency_id'] .
        $data['wsb_total'] .
        env('WEBPAY_SECRET_KEY')
    );

    if ($data['wsb_signature'] !== $expected) {
        Log::warning('Webpay: invalid signature', $data);
        return response('ERROR', 400);
    }

    if ((int)$data['wsb_result_code'] === 1) {
        $orderId = (int)$data['wsb_order_num'];
        Order::where('id', $orderId)->update([
            'status'         => 'paid',
            'transaction_id' => $data['wsb_transaction_num'] ?? null,
        ]);
    }

    return response('OK');
}

wsb_result_code: 1 — успех, 2 — отказ, 3 — отмена покупателем.

Что делать на странице возврата?

Не полагайтесь на параметры в returnUrl — используйте статус заказа из БД, который обновлён notify-обработчиком:

public function return(Request $request): View
{
    $orderId = $request->input('wsb_order_num');
    $order = Order::findOrFail($orderId);
    return view('payment.result', ['paid' => $order->status === 'paid', 'order' => $order]);
}

Как обрабатывать возвраты через Webpay?

Возвраты выполняются через административную панель Webpay или API. Убедитесь, что сумма возврата не превышает первоначальную. Для отладки используйте тестовую среду: проверьте, что на тестовом сертификате срок действия не истёк. При API-возврате подпись формируется по тому же алгоритму, но с параметрами операции.

Что делать при таймауте соединения?

Если запрос к Webpay не отвечает более 30 секунд, инициируйте повторный запрос с тем же order_num. Idempotency гарантируется уникальностью order_num — повторная отправка с тем же номером не создаст дубль. Установите таймаут на стороне клиента и логируйте все таймауты для анализа.

Сравнение тестовой и боевой среды

Параметр Тестовая среда Боевая среда
URL test.webpay.by payment.webpay.by
wsb_test 1 0
Карты Тестовые из документации Реальные карты
Активация Мгновенно 1–3 рабочих дня после теста

Таблица кодов ошибок и их обработка

Код результата Описание Действие
1 Успешный платёж Обновить статус заказа на «оплачен»
2 Отказ банка Уведомить клиента и предложить другую карту
3 Отмена покупателем Вернуть на страницу корзины
Другое Техническая ошибка Записать в лог и вернуть HTTP 400

При тестировании возвратов сверяйте суммы и используйте те же ключи. Все сценарии нужно прогонять до перехода в боевой режим.

Процесс работы: от аналитики до деплоя

  1. Аналитика — изучаем ваш магазин, выбираем способ интеграции (готовые модули или кастом).
  2. Проектирование — согласовываем схему потока платежей, URL уведомлений.
  3. Реализация — внедряем форму оплаты, обработчики, возвраты.
  4. Тестирование — прогоняем все сценарии в тестовой среде: успех, отказ, таймаут.
  5. Деплой — активируем боевой режим, мониторим первые транзакции.

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

  • Документация по интеграции (схема, описание методов).
  • Тестирование 10+ сценариев платежей.
  • Обучение вашего администратора работе с возвратами и отчётами Webpay.
  • Поддержка в течение 30 дней после запуска.

Сроки и стоимость

Интеграция Webpay занимает от 5 до 10 рабочих дней в зависимости от сложности магазина. Стоимость рассчитывается индивидуально. Оценим проект бесплатно после знакомства с вашим сайтом — свяжитесь с нами. Закажите интеграцию и получите консультацию инженера.

Почему стоит доверить интеграцию нам?

Более 10 лет опыта в веб-разработке, 50+ успешно запущенных интеграций с платёжными системами. Гарантируем корректную обработку всех типов транзакций и отсутствие ошибок подписи. Наши решения проходят аудит безопасности. Получите консультацию — оценим ваш проект за 1 день.

Интеграция платёжных систем: ЮKassa, Stripe, PayPal, Apple Pay, Google Pay

Конверсия упала на 12% сразу после редизайна. Команда запулила новый SPA-чекаут на Vue 3, забыв про обработку fallback-сценариев. Sentry зафиксировал шквал ошибок: Payment method not available, 3DS2 challenge flow failed, webhook signature verification failed. Пользователи бросали корзину на этапе выбора способа оплаты. Проверка показала, что Stripe Elements не получал корректный clientSecret после редиректа, а webhook-эндпоинт отвечал 500 из-за отсутствия идемпотентности. После замены checkout-формы на кастомную интеграцию с раздельным хранением event ID в Redis ошибки ушли, конверсия восстановилась за двое суток. Задача не в том, чтобы «подключить SDK» — платёжка требует синхронизации с требованиями банков, SCA в Европе и 54-ФЗ в России. Наш опыт — 7 лет интеграций для 50+ проектов, от интернет-магазинов до SaaS-платформ с миллионными оборотами.

Что входит в работу под ключ

  • Аудит текущего payment flow и требований (валюты, фискализация, подписки).
  • Выбор провайдера с учётом географии и бизнес-модели.
  • Backend-интеграция (Laravel/Node.js/Go) с обработкой webhook'ов, идемпотентностью и ретраями.
  • Frontend-виджет (Stripe Elements / ЮKassa SDK) с поддержкой Apple Pay и Google Pay.
  • Тестирование всех сценариев: успех, отказ, 3DS, возвраты, чек коррекции.
  • Мониторинг первых транзакций и документация.

Оценим проект за 1 день — для получения консультации напишите в чат.

Сравнение провайдеров: что выбрать

Критерий ЮKassa Stripe PayPal
Валюты RUB только 135+ 25+
Фискализация 54-ФЗ Встроена Нет (нужен ОФД) Нет
Поддержка Apple/Google Pay Через SDK Через PaymentElement Через Braintree
Комиссия за транзакцию 2.5–4% 2.9% + $0.30 2.99% + $0.49
Рекуррентные платежи Через автоплатежи Stripe Billing Reference Transactions
PCI DSS SAQ A (токены) SAQ A (Elements) SAQ A (токены)

Stripe выигрывает по гибкости: 135+ валют против одной у ЮKassa. Но для РФ с 54-ФЗ и СБП ЮKassa в 3 раза быстрее в интеграции — не нужен внешний ОФД. Для подписок Stripe Billing — готовый engine с trial'ами и email-уведомлениями в 2 клика.

Как выбрать подходящего провайдера?

Ключевых точек три. Где живут ваши клиенты? Только РФ — ЮKassa, глобально — Stripe. Нужна ли фискализация по 54-ФЗ? Да — ЮKassa, иначе Stripe + облачный ОФД. Планируете ли подписки? Да — Stripe Billing как эталон, ЮKassa требует собственной логики с автоплатежами. Экономия на комиссиях при выборе правильного провайдера — до 1.5% с оборота. Для проекта с 2 млн ₽ в месяц это 360 000 ₽ в год.

Где прячутся реальные сложности

Подключить тестовый режим — час. Правильно обработать все сценарии — несколько недель.

Webhook надёжность. Webhook может не дойти — сервер недоступен, таймаут, сеть. Провайдер повторяет с экспоненциальным backoff (Stripe — до 3 дней). Обработчик обязан быть идемпотентным: если payment.succeeded придёт дважды с одним payment_id, заказ обновится только раз. Реализуется через хранение event ID в Redis с TTL.

3DS2 и redirect flow. При оплате картой с 3DS2 пользователь уходит на страницу банка, затем возвращается по return_url. За это время сессия могла истечь, корзина очиститься. Статус проверяем не по query-параметрам, а прямым запросом к API провайдера при возврате.

Частичные возвраты и чеки. Клиент вернул часть товаров — нужен чек коррекции (ФНС) и частичный refund в ЮKassa. Stripe делает partial_refund нативно. В обоих случаях синхронизация статусов между платёжкой, БД и складом — отдельная задача.

Валютные ограничения. ЮKassa — только рубли. Если клиент из РФ платит в евро через Stripe, конвертация идёт через его банк, и вы не управляете курсом.

Почему webhook'и требуют идемпотентности?

Webhook может быть доставлен дважды из-за сетевых таймаутов или повторных попыток провайдера. Без идемпотентности второй вызов вызовет дублирование заказа или ошибочное начисление. Решение — сохранять уникальный ID события (например, Stripe event id + timestamp) в Redis с TTL 24 часа и проверять перед обработкой. Если ID уже существует — возвращаем 200, не выполняя бизнес-логику. Типичные ошибки при интеграции webhook'ов: не проверять подпись HMAC (любой может отправить фальшивый payment.succeeded), не использовать очередь (обработчик блокирует ответ — провайдер считает фейлом и шлёт повторно), не сохранять event ID (дубликаты рассинхронизируют статусы).

Как строим интеграцию

Архитектура. Никогда не храним данные карт — только токены провайдера. Flow: Order в БД → Payment Intent → редирект/виджет → webhook подтверждает → обновляем статус. База истины — статус в платёжной системе.

Для Laravel используем stripe/stripe-php или yookassa-sdk. Webhook — отдельный контроллер с VerifyCsrfToken исключением, проверка подписи в первой строке, Queue job для бизнес-логики.

Для Next.js/React — @stripe/stripe-js + @stripe/react-stripe-js. PaymentElement включает Apple/Google Pay автоматически. Пример:

const stripe = await stripePromise;
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: { return_url: 'https://example.com/order/thank-you' },
});

Тестирование. Stripe CLI: stripe listen --forward-to localhost:8000/webhook. Тест-карты для всех сценариев (3DS, decline, insufficient funds). Cypress-тест checkout flow в CI — обязательная гарантия стабильности.

Мы отлаживали интеграцию Stripe Billing для SaaS с 50 000 подписчиков. Проблема возникла с обработкой invoice.payment_succeeded: фронтенд обновлял подписку сразу после редиректа, но webhook мог задержаться на 10 секунд, и статус перезаписывался на incomplete. Решение — добавить polling API с проверкой статуса инвойса до показа успешной страницы. Это снизило количество ошибочных отписок на 18%.

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

Аудит → выбор провайдера → backend → frontend → тесты → деплой → мониторинг.

Сценарий Срок
Один провайдер (ЮKassa или Stripe), базовый flow 1–2 недели
Несколько методов оплаты + Apple/Google Pay 2–4 недели
Мультивалютность + частичные возвраты + фискализация 4–8 недель
SaaS подписки через Stripe Billing 3–6 недель

Стоимость рассчитывается индивидуально. Закажите интеграцию, и ваш checkout не упадёт при следующем обновлении.

Ссылки:

Гарантируем: 7 лет опыта, 50+ успешных интеграций. Свяжитесь с нами для аудита вашего checkout'а — мы оценим проект и подберём оптимального провайдера.