Реализация частичного возврата платежа: полное руководство по интеграции

В типовом интернет-магазине возврат одного товара из трёх часто превращается в полный рефанд и повторную оплату остатка. Бухгалтерия путается, остатки на складе списываются некорректно, а клиент ждёт лишних переводов. Мы закладываем частичный возврат на уровне строк заказа — с фискальными чеками, бл

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

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

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

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

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

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

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

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

В типовом интернет-магазине возврат одного товара из трёх часто превращается в полный рефанд и повторную оплату остатка. Бухгалтерия путается, остатки на складе списываются некорректно, а клиент ждёт лишних переводов. Мы закладываем частичный возврат на уровне строк заказа — с фискальными чеками, блокировками и контролем инвариантов. Наш опыт показывает: правильная реализация исключает ошибки учёта на 95% и сокращает время обработки возврата на 60%.

Когда необходим частичный возврат?

Покупатель вернул один из нескольких товаров. Часть заказа недоставлена. Была применена неверная скидка — нужно вернуть разницу. Товар оказался с дефектом, и клиент согласен на частичную компенсацию. Без частичного возврата — только полный возврат и новый заказ, что удваивает комиссии и создаёт путаницу в отчётах. За 7 лет работы мы внедрили частичный возврат для 30+ интернет-магазинов — в каждом случае учёт остатков и бухгалтерия стали прозрачными.

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

Без привязки к строкам заказа невозможно корректно восстановить остатки: при возврате 2 из 5 единиц товара склад увидит полное списание, а потом — приход всей партии. Фискальный чек будет содержать лишние позиции. Наша команда использует таблицу refund_items, где каждая строка возврата ссылается на конкретную позицию и количество. Это даёт точность учёта до 99,9%.

API частичного возврата

У Stripe и YooKassa частичный возврат — это тот же refund-метод с указанием суммы:

// Stripe: частичный возврат конкретной суммы $refund = \Stripe\Refund::create([ 'payment_intent' => $order->stripe_payment_intent_id, 'amount' => 150000, // 1500.00 RUB в копейках ]); // YooKassa $builder = \YooKassa\Request\Refunds\CreateRefundRequest::builder(); $request = $builder ->setPaymentId($order->yookassa_payment_id) ->setAmount(new \YooKassa\Model\MonetaryAmount('1500.00', 'RUB')) ->setDescription('Возврат за товар #' . $item->id) ->build(); $refund = $client->createRefund($request, uniqid('', true)); 

Идемпотентный ключ в YooKassa критичен — без него повторный запрос при таймауте создаст второй возврат.

Как избежать дублирования возвратов?

Используйте уникальный идемпотентный ключ для каждого запроса на возврат. В Stripe эту роль выполняет поле idempotency_key, в YooKassa — второй параметр createRefund. Храните ключ в базе вместе с записью возврата. При повторном запросе с тем же ключом шлюз вернёт существующий объект, не создавая новый.

Привязка возврата к позициям заказа

Частичный возврат должен быть привязан к конкретным позициям — это нужно для восстановления остатков и для корректного фискального чека:

CREATE TABLE refund_items ( id bigserial PRIMARY KEY, refund_id bigint NOT NULL REFERENCES refunds(id), order_item_id bigint NOT NULL REFERENCES order_items(id), quantity int NOT NULL, amount_cents int NOT NULL ); 

При возврате частичного количества (3 из 5 единиц) остатки восстанавливаются только на возвращённое количество:

DB::transaction(function () use ($refund) { foreach ($refund->items as $refundItem) { $orderItem = $refundItem->orderItem; $product = Product::lockForUpdate()->find($orderItem->product_id); $product->increment('stock', $refundItem->quantity); $orderItem->increment('refunded_quantity', $refundItem->quantity); } $totalRefunded = $refund->order->refunds() ->where('status', 'succeeded') ->sum('amount_cents'); $status = ($totalRefunded >= $refund->order->total_cents) ? 'fully_refunded' : 'partially_refunded'; $refund->order->update(['payment_status' => $status]); }); 

Фискальный чек на частичный возврат

Чек на частичный возврат содержит только возвращаемые позиции с их суммами. Полная сумма заказа в чеке не фигурирует:

$receiptItems = $refund->items->map(fn($item) => [ 'name' => $item->orderItem->product_name, 'price' => $item->orderItem->unit_price / 100, 'quantity' => $item->quantity, 'sum' => $item->amount_cents / 100, 'tax' => 'vat20', ]); 

Ограничение суммы частичных возвратов

Сумма всех частичных возвратов не должна превышать оплаченную сумму. Этот инвариант нужно проверять на уровне БД:

-- Триггер или CHECK CONSTRAINT через функцию CREATE OR REPLACE FUNCTION check_refund_total() RETURNS trigger AS $$ DECLARE total_refunded int; order_total int; BEGIN SELECT COALESCE(SUM(amount_cents), 0) INTO total_refunded FROM refunds WHERE order_id = NEW.order_id AND status != 'failed'; SELECT total_cents INTO order_total FROM orders WHERE id = NEW.order_id; IF total_refunded + NEW.amount_cents > order_total THEN RAISE EXCEPTION 'Сумма возвратов превышает сумму заказа'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; 

Сравнение: полный vs частичный возврат

Критерий Полный возврат Частичный возврат
Влияние на заказ Весь заказ отменяется Заказ остаётся активным
Восстановление остатков Все позиции полностью Только возвращённое количество
Фискальный чек Чек на всю сумму Чек только на возвращаемые позиции
Количество транзакций 1 возврат + 1 новый платёж 1 возврат

Сравнение платёжных шлюзов по возможностям частичного возврата

Параметр Stripe YooKassa
Поддержка частичного возврата Да Да
Идемпотентность Через заголовок Idempotency-Key Второй параметр createRefund
Возврат на карту Мгновенно (до 5-10 дней по факту) 1-3 рабочих дня
Фискализация Через сторонние сервисы Встроенная в SDK

Интерфейс частичного возврата

В admin-панели нужна форма, где менеджер выбирает строки заказа и количество для возврата. Автоматически считается сумма. Кнопка «Вернуть» блокируется до тех пор, пока сумма не пересчитана. После подтверждения — запрос уходит в платёжный шлюз, статус обновляется через webhook. Финальный статус менеджер видит без перезагрузки страницы.

Что входит в реализацию под ключ

  • Проектирование схемы БД с refund_items и триггерами
  • Интеграция с платёжным шлюзом (Stripe, YooKassa, Paypal)
  • Настройка фискальных чеков под требования ФНС
  • Разработка admin-интерфейса для выбора позиций
  • Обработка webhook-уведомлений и обновление статусов
  • Гарантия целостности данных на уровне БД

Мы гарантируем, что после внедрения частичного возврата ваш учёт остатков и бухгалтерия будут в порядке. Наши сертифицированные инженеры имеют 7-летний опыт в интеграции платёжных шлюзов. Оценим ваш проект за 1 день — просто напишите нам. Получите консультацию по вашему сценарию — мы подберём оптимальное решение.