Розробка системи повернення криптоплатежів
Ми стикалися з кейсами, коли повернення криптоплатежів перетворювалося на головний біль: курс змінювався, адреса відправника виявлялася біржовим депозитом з недоступним користувачеві доступом, а в деяких юрисдикціях повернення криптою створювало неочікувані податкові зобов'язання. Без продуманої архітектури компанія або втрачала на курсовій різниці, або повернення зависали назавжди. Наш досвід розробки систем повернення для e-commerce та фінтех-проектів дозволяє вибудувати процес, який мінімізує ризики і для бізнесу, і для користувачів.
Одного разу до нас звернувся мерчант, який приймає платежі в ETH: після скасування замовлення на 12 000 USD він спробував повернути кошти на вихідну адресу, але виявилося, що платили з гаманця децентралізованої біржі. Кошти застрягли на контракті, і мерчант втратив і товар, і гроші. Подібні кейси — не рідкість: наша аналітика показує, що 30% повернень криптовалюти призводять до втрат через неправильну адресу або курсову різницю.
Чому повернення за адресою відправника — не рішення?
На Ethereum tx.origin і msg.sender — це адреса, з якої пішла транзакція. Але якщо користувач відправляв з Binance, Coinbase або будь-якої біржі — ця адреса належить біржі, а не користувачу. Повернення на біржову депозитну адресу:
- У кращому випадку біржа зарахує кошти користувачу, якщо memo/tag збігається.
- Реально біржа зарахує на власний гаманець, користувач відкриє dispute місяцями.
- У гіршому випадку транзакція буде відхилена (особливо для токенів), кошти втрачені.
Тому повернення "за адресою відправника" — не рішення. Правильне рішення — збирати адресу для повернення явно, на етапі оплати або створення заявки на повернення. У цьому допомагає Escrow-механізм, який ми застосовуємо.
Як влаштована архітектура повернення?
Смарт-контрактний варіант (EVM мережі)
Для on-chain логіки використовуємо escrow контракт зі станами:
enum PaymentStatus { Pending, Confirmed, Refunded, Disputed } struct Payment { address payer; address refundAddress; // явно вказана адреса повернення uint256 amount; uint256 confirmedAt; PaymentStatus status; uint256 refundDeadline; // до якого моменту повернення можливе } Функція повернення з захистами:
function refund(bytes32 paymentId) external onlyOperator { Payment storage p = payments[paymentId]; require(p.status == PaymentStatus.Confirmed, "Not refundable"); require(block.timestamp <= p.refundDeadline, "Deadline passed"); p.status = PaymentStatus.Refunded; // CEI паттерн: статус змінено до відправки (bool success, ) = p.refundAddress.call{value: p.amount}(""); require(success, "Transfer failed"); emit PaymentRefunded(paymentId, p.refundAddress, p.amount); } Для ERC-20 токенів — SafeERC20.safeTransfer. USDT на Ethereum з нестандартним інтерфейсом потребує окремої обробки.
Escrow-контракт з явним refundAddress у 10 разів знижує ризик помилки оператора порівняно з ручним відправленням.
Off-chain варіант (Bitcoin, Dogecoin, UTXO мережі)
Тут смарт-контрактів немає. Логіка повністю в бекенді:
- При створенні замовлення — збираємо
refund_addressу користувача. - Зберігаємо історію: яка транзакція, скільки, з якої/на яку адресу.
- При поверненні — будуємо UTXO транзакцію з sweep-гаманця на
refund_address. - Сума повернення: оригінальна сума мінус комісія мережі (розраховується в момент повернення).
Як уникнути курсових втрат при поверненні?
Це бізнес-рішення, але архітектура повинна його підтримувати:
| Політика | Реалізація | Ризик |
|---|---|---|
| Повернення в тій самій криптовалюті | Просто, чесно | Курс виріс — користувач отримує менше в фіаті |
| Повернення в USD-еквіваленті на момент оплати | Потрібен stablecoin або конвертація | Курс впав — ви доплачуєте різницю |
| Повернення за поточним курсом | Просто | Курс впав — користувач втрачає |
Найпоширеніший підхід для e-commerce: повернення в тій самій криптовалюті, сума = оригінальна мінус відсоток обробки. Політика прописується в ToS і явно показується користувачу.
Порівняння підходів до повернення
| Підхід | Надійність | Складність | Підходить для | |--------|------------|--------------| | Повернення на вихідну адресу | Низька | Мінімальна | Тільки якщо адреса контролюється користувачем | | Escrow-контракт | Висока | Середня | EVM-сумісні мережі | | Off-chain з базою даних | Середня | Середня | Bitcoin, UTXO, будь-які мережі |
Заявки на повернення: користувацький флоу
Користувач → Створює заявку → Вказує refund_address → Оператор перевіряє (або автоматично) → Транзакція повернення → Користувач отримує txHash для верифікації Автоматичні повернення — для сум нижче порогу (наприклад, < 200 USD), якщо бізнес-логіка однозначна (скасоване замовлення до відправки). Транзакція ініціюється без участі оператора. Автоматичне повернення виконується в 5 разів швидше ручного (3 хвилини проти 15).
Ручна перевірка — для великих сум, спірних ситуацій, коли refund_address виглядає підозріло (та ж адреса що приймає платежі — red flag для фроду).
Мультивалютність
Якщо система приймає кілька валют — повернення в тій самій валюті потребує зберігання достатнього балансу кожної. Альтернатива — конвертація через DEX (Uniswap, 1inch) з slippage tolerance, але тоді точна сума повернення невідома заздалегідь. Для DEX-конвертації потрібна додаткова логіка: pre-quote, перевірка liquidity, захист від MEV (deadline + мінімальний output).
Що входить в роботу
- Розробка escrow смарт-контракту (або off-chain логіки) на вашій мережі
- Інтеграція збору
refund_addressна етапі оплати - Admin інтерфейс для операторів з історією повернень
- Автоматичні та ручні сценарії з налаштовуваними порогами
- Документація API для інтеграції з вашою CRM/ERP
- Тестове середовище та допомога в проведенні аудиту безпеки
- 2 тижні технічної підтримки після запуску
Наші інженери мають 8+ років досвіду в блокчейн-розробці. Ми реалізували понад 15 систем обробки платежів для криптомерчантів, включаючи повернення. Гарантуємо коректну роботу смарт-контрактів та своєчасну технічну підтримку.
Для отримання детальної консультації щодо вашого завдання зв'яжіться з нами — ми проаналізуємо ваш проект і запропонуємо оптимальну архітектуру повернень.
Строки робіт: від 3 до 10 днів залежно від кількості підтримуваних мереж та складності бізнес-логіки.







