Реализация Split-платежей (расщепление оплаты) на сайте

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Реализация Split-платежей (расщепление оплаты) на сайте
Сложный
~3-5 дней
Часто задаваемые вопросы

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

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

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

  • 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

Реализация Split-платежей (расщепление оплаты) на сайте

Split-платежи — разбивка одной транзакции покупателя на несколько получателей одновременно. Типичный кейс — маркетплейс с 50 продавцами, где каждый заказ нужно разделить между продавцом, платформой и партнёрской программой. Без системы split-платежей бухгалтер тратит 3 часа в день на ручную разноску — с нашей реализацией время сокращается до 15 минут, а 95% возвратов обрабатываются автоматически. Другие сценарии: booking-сервис с комиссией агрегатора, подписка с revenue share между партнёрами.

Мы проектируем и реализуем split-платежи под ключ: от выбора провайдера до мониторинга и фискализации. Реализация занимает от 5 до 14 рабочих дней в зависимости от количества получателей, логики распределения и используемого платёжного провайдера. Закажите аудит вашей платёжной системы — найдём узкие места и предложим оптимальное решение.

Почему split-платежи требуют правильной архитектуры?

Некорректное расщепление приводит к финансовым расхождениям, проблемам с рефандами и налоговым рискам. Например, если не использовать transfer_group в Stripe, при возврате трансферы не отменяются автоматически, и деньги могут потеряться. Архитектура должна учитывать обработку ошибок, округление копеек и мониторинг. Наши инженеры с 10-летним опытом строят надёжные схемы, которые экономят до 20% времени на бухгалтерию.

Как выбрать модель расщепления?

Есть два принципиально разных подхода — Charge + Transfer и Direct Charge, и выбор между ними определяет всё остальное.

Параметр Charge + Transfer Direct Charge
Движение денег Средства приходят на счёт платформы, затем переводятся продавцам Покупатель платит напрямую продавцу, платформа получает комиссию
Ответственность за KYC Платформа обязана проверять продавцов Продавцы проходят KYC самостоятельно
Контроль над рефандами Платформа управляет возвратами централизованно Возвраты — на стороне продавца, платформа может не участвовать
Сложность интеграции Выше, требуется настройка webhook-ов и трансферов Ниже, но нужна обработка application fee
Юридические риски Выше (платформа — налоговый агент) Ниже, но требуется договор с каждым продавцом

Для большинства маркетплейсов на ранней стадии проще Charge + Transfer — меньше юридической сложности при онбординге продавцов.

Как работает Charge + Transfer в Stripe?

Stripe Connect — де-факто стандарт для split-платежей. Сначала создаём PaymentIntent на полную сумму, затем в обработчике webhook выполняем трансферы:

$paymentIntent = \Stripe\PaymentIntent::create([
    'amount' => $order->total_cents,
    'currency' => 'eur',
    'payment_method_types' => ['card'],
    'metadata' => [
        'order_id' => $order->id,
        'split_recipients' => json_encode($order->recipients),
    ],
]);

// В webhook-обработчике
public function handlePaymentSucceeded(array $payload): void
{
    $intent = $payload['data']['object'];
    $recipients = json_decode($intent['metadata']['split_recipients'], true);

    foreach ($recipients as $recipient) {
        \Stripe\Transfer::create([
            'amount' => $recipient['amount_cents'],
            'currency' => $intent['currency'],
            'destination' => $recipient['stripe_account_id'],
            'transfer_group' => $intent['transfer_group'],
            'source_transaction' => $intent['charges']['data'][0]['id'],
        ]);
    }
}

transfer_group связывает все трансферы с исходным платежом — это критично для корректного рефанда. source_transaction гарантирует, что трансфер выполняется только из средств конкретного платежа, а не из общего баланса. Подробнее о механизме — в документации Stripe Connect: Charge Transfers.

Хранение конфигурации расщепления

Правила split хранятся в БД, не в коде — иначе каждое изменение комиссии требует деплоя. Пример схемы: таблица split_rules с полями entity_type, entity_id, rule_type (percentage, fixed, remainder), value, priority. Расчёт долей происходит перед созданием трансферов, причём правило remainder должно быть ровно одно — это защита от округления и накопленных ошибок. Сумма долей обязана совпадать с total до копейки.

class SplitCalculator
{
    public function calculate(int $totalCents, array $rules): array
    {
        $allocated = 0;
        $result = [];

        // Сначала фиксированные суммы
        foreach ($rules as $rule) {
            if ($rule['rule_type'] === 'fixed') {
                $result[] = ['recipient' => $rule['entity_id'], 'amount' => $rule['value']];
                $allocated += $rule['value'];
            }
        }

        // Затем процентные
        foreach ($rules as $rule) {
            if ($rule['rule_type'] === 'percentage') {
                $amount = (int) round($totalCents * $rule['value'] / 100);
                $result[] = ['recipient' => $rule['entity_id'], 'amount' => $amount];
                $allocated += $amount;
            }
        }

        // Остаток — платформе или last-in-line получателю
        $remainder = $totalCents - $allocated;
        foreach ($rules as $rule) {
            if ($rule['rule_type'] === 'remainder') {
                $result[] = ['recipient' => $rule['entity_id'], 'amount' => $remainder];
                break;
            }
        }

        return $result;
    }
}

Как обрабатывать возвраты при split-платежах?

Возврат при расщеплённом платеже — самое болезненное место. Stripe автоматически не отзывает трансферы при рефанде на PaymentIntent — это нужно делать явно. Алгоритм: 1) рефанд основного платежа, 2) реверс трансферов пропорционально сумме возврата. Если на аккаунте получателя недостаточно средств для реверса, Stripe вернёт ошибку — тогда требуется ручное дебетование.

public function refund(Order $order, int $refundCents): void
{
    // 1. Рефанд основного платежа
    \Stripe\Refund::create([
        'payment_intent' => $order->stripe_payment_intent_id,
        'amount' => $refundCents,
        'refund_application_fee' => true,
    ]);

    // 2. Реверс трансферов пропорционально
    $ratio = $refundCents / $order->total_cents;
    foreach ($order->transfers as $transfer) {
        $reverseAmount = (int) round($transfer->amount_cents * $ratio);
        \Stripe\Transfer::createReversal($transfer->stripe_transfer_id, [
            'amount' => $reverseAmount,
            'refund_application_fee' => true,
        ]);
    }
}

Типичные ошибки при возвратах

  • Забыли отменить refund_application_fee – платформа теряет комиссию.
  • Неверно рассчитали пропорцию из-за округления – копеечные расхождения накапливаются.
  • Не обработали частичный возврат, когда перевод уже реверсирован частично.

Альтернативы Stripe

Провайдер Модель split Гибкость Фискализация Регион
Stripe Connect Charge + Transfer / Direct Charge Высокая Требуется отдельная Global
CloudPayments Receipt с несколькими получателями Средняя Встроенная СНГ
YooKassa Deal Deal API Средняя Встроенная РФ
Fondy Партнёрский договор Низкая На стороне провайдера Украина

В среднем интеграция с Stripe Connect даёт на 30% больше контроля над транзакциями, чем аналоги CloudPayments, но требует больше времени на настройку. Выбор провайдера зависит от географии и требований к фискализации.

Что делать при расхождениях в мониторинге?

Каждый день запускается reconciliation job — сравнение сумм трансферов в БД с реальными трансферами в Stripe через API. Расхождения уходят в алерт. Это не паранойя — webhook-и иногда теряются, особенно при деплоях в момент транзакции. Настроив мониторинг, вы сократите финансовые потери от таких сбоев на 10–15%.

$stripeTransfers = \Stripe\Transfer::all([
    'created' => ['gte' => $yesterday->timestamp, 'lt' => $today->timestamp],
    'limit' => 100,
]);

$dbTransfers = Transfer::whereDate('created_at', $yesterday)->get()->keyBy('stripe_id');

foreach ($stripeTransfers->autoPagingIterator() as $transfer) {
    if (!isset($dbTransfers[$transfer->id])) {
        Log::critical('Untracked transfer', ['stripe_id' => $transfer->id, 'amount' => $transfer->amount]);
    }
}

Что входит в работу по реализации split-платежей

  • Анализ бизнес-логики и выбор оптимальной модели расщепления.
  • Интеграция с платёжным провайдером (Stripe, CloudPayments, YooKassa).
  • Настройка правил распределения и хранение в БД.
  • Реализация обработки рефандов и реверсов трансферов.
  • Настройка webhook-ов и мониторинга.
  • Документация API и инструкции для бухгалтерии.
  • Обучение команды работе с платёжной системой.
  • Поддержка после запуска (1 месяц).

Налоговые и юридические аспекты

Расщепление платежа не освобождает платформу от фискальных обязательств — в большинстве юрисдикций платформа является налоговым агентом. Это означает передачу данных о выплатах в налоговые органы (в РФ — ФНС, в ЕС — DAC7 reporting). Нужно учитывать это при проектировании схемы split ещё на старте — переделывать потом дороже. Обратите внимание на требования DAC7 Directive при работе в Европе.

Свяжитесь с нами для оценки вашего проекта — мы поможем выбрать оптимальное решение и реализуем его в кратчайшие сроки. Наш опыт — 5+ лет в разработке платёжных систем, более 15 успешных проектов с split-платежами. Получите консультацию уже сегодня.

Интеграция платёжных систем: Ю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'а — мы оценим проект и подберём оптимального провайдера.