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

У типовому інтернет-магазині повернення одного товару з трьох часто перетворюється на повний рефанд та повторну оплату залишку. Бухгалтерія плутається, залишки на складі списуються некоректно, а клієнт чекає зайвих переказів. Ми закладаємо часткове повернення на рівні рядків замовлення — з фіскальни

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

Інформаційні сайти або веб-програми
Сайти візитки, 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
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • 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%.

Коли необхідне часткове повернення?

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

Чому часткове повернення має бути прив'язане до позицій замовлення?

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

API часткового повернення

У Stripe та YooKassa часткове повернення — це той самий refund-метод із зазначенням суми:

// Stripe: часткове повернення конкретної суми $refund = \Stripe\Refund::create([ 'payment_intent' => $order->stripe_payment_intent_id, 'amount' => /* сума розраховується індивідуально */, ]); // YooKassa $builder = \YooKassa\Request\Refunds\CreateRefundRequest::builder(); $request = $builder ->setPaymentId($order->yookassa_payment_id) ->setAmount(new \YooKassa\Model\MonetaryAmount(/* сума залежить від замовлення */, '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-сповіщень та оновлення статусів
  • Гарантія цілісності даних на рівні БД

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