Розробка аукціонної площадки
Аукціонна платформа — один з технічно навантажених типів торгових площадок: ставки мають оброблятися в режимі реального часу, система захищена від race conditions, таймер синхронізований між усіма учасниками. Типи: англійський аукціон (ставки зростають), голландський (ціна падає), закриті торги, аукціони з резервною ціною.
Типи аукціонів
Англійський (восходящий): учасники підвищують ставку. Переможує останній, хто розмістив найбільшу ставку до закінчення часу. Anti-sniping: якщо ставка розмісцена в останні N секунд — таймер автоматично продовжується.
Голландський (нисходящий): ціна починається високо та падає автоматично. Перший, хто натиснув «Купити», отримує лот за поточною ціною. Застосовується для швидкопсувних товарів, квітів.
Закриті торги (sealed-bid): всі учасники подають ставку один раз, не бачачи чужих. Переможує найбільша ставка. Застосовується на тендерних площадках.
Автоматична ставка (proxy bidding): учасник вказує максимальну ціну, система автоматично піднімає ставку до перемоги або вичерпання ліміту.
Race Conditions та конкурентні ставки
Головна технічна проблема: два учасники одночасно надсилають ставку — хто переможе?
Рішення через оптимістичну блокування у PostgreSQL:
-- Атомарне оновлення ставки з перевіркою версії
UPDATE auctions
SET current_bid = $new_bid,
current_bidder_id = $user_id,
version = version + 1,
updated_at = NOW()
WHERE id = $auction_id
AND version = $expected_version -- перевіряємо, що ніхто не встиг раніше
AND current_bid < $new_bid; -- ставка вища за поточну
-- Якщо UPDATE не вплинув на 0 рядків — ставка застаріла, повертаємо помилку
Альтернатива для високої навантаженості — Redis SETNX + Lua script для атомарного оновлення поточної ставки.
Оновлення в реальному часі
Всі учасники аукціону мають бачити оновлення ставок в реальному часі:
- WebSocket-підключення при входу на сторінку аукціону
- При новій ставці — broadcast в кімнату аукціону:
{auction_id, new_bid, bidder_name_masked, remaining_time} - Таймер синхронізується з сервером кожні 10 секунд (не покладається на client-side clock)
// Socket.io на сервері
io.to(`auction:${auctionId}`).emit('bid_placed', {
bidAmount: bid.amount,
bidderAlias: `Учасник ${bid.alias}`,
remainingSeconds: auction.endsAt - Date.now(),
});
Депозити та блокування коштів
Для серйозних торгів учасник вносить депозит перед участю — гарантія намірів. При перемозі депозит засчитується в оплату; при програші — повертається.
Реалізація: Stripe PaymentIntent з capture = manual. Кошти авторизовані (заблоковані), але не списані. Після перемоги — capture. Після програші — cancel авторизації.
Система сповіщень
- Вас перебили → негайно (push/email)
- 1 годину до кінця → нагадування
- Переможили → поздоровлення + інструкція по оплаті
- Аукціон завершений без вашої перемоги → результати
Escrow та оплата
Після перемоги: звичайна схема — покупець платить → продавець відправляє → покупець підтверджує → кошти продавцю. Додатково: страховка від шахрайства (опис не відповідає).
Модерація лотів
Перед стартом аукціону лот проходить модерацію: відповідність правилам платформи, перевірка документів права собственності (для дорогих товарів), підтвердження наявності товару.
Терміни
MVP (англійський аукціон, ставки з race condition protection, realtime WebSocket, базові сповіщення): 3–4 місяці. Повноцінна платформа з proxy bidding, кількома типами аукціонів, депозитами та escrow: 5–8 місяців.







