Защита от переплаты кошельком и улучшение отображения транзакций
Изменения в UI (order_form.html): - Добавлен data-code к опциям способов оплаты для идентификации метода кошелька - ID для селекта способа оплаты (payment-method-select) и поля суммы (payment-amount-input) - Динамическое ограничение max на поле суммы платежа при выборе кошелька - Подсказка 'Макс: X руб.' отображается только для оплаты кошельком - Для внешних методов (карта, наличные) ограничение отсутствует — переплата допустима Логика JS: - При выборе метода с code == 'account_balance' устанавливается max = order.amount_due - Для остальных методов max удаляется — оператор может внести сумму больше остатка - Переплата по внешним методам корректно зачисляется в кошелёк через WalletService.add_overpayment Серверная защита (transaction_service.py): - В TransactionService.create_payment добавлена проверка: если payment_method.code == 'account_balance' и amount > order.amount_due — ValidationError - Сообщение: 'Сумма оплаты из кошелька (X руб.) не может превышать остаток к оплате (Y руб.)' - Защита от обхода UI через API или прямой вызов Улучшение отображения (order_form.html, order_detail.html): - Для возврата в кошелёк (transaction_type == 'refund' и code == 'account_balance') показываем 'на баланс счёта' вместо названия метода - История становится понятнее: '−750,00 руб. Возврат 29.11.2025 на баланс счёта' Сценарий: - Кошелёк клиента 500 руб., заказ 65 руб. - Оператор выбирает оплату из кошелька — поле суммы ограничено 65 руб. - Попытка ввести 500 заблокирована UI и серверной валидацией - Для внешней оплаты (карта онлайн) можно внести 500 руб. — остаток 435 автоматически зачислится в кошелёк как переплата Цель: - Исключить путаницу в истории транзакций при оплате кошельком - Разграничить поведение: кошелёк строго ограничен, внешние методы допускают переплату - Обеспечить прозрачность движения средств для операторов
This commit is contained in:
@@ -54,6 +54,13 @@ class TransactionService:
|
||||
except PaymentMethod.DoesNotExist:
|
||||
raise ValueError(f'Способ оплаты "{payment_method}" не найден')
|
||||
|
||||
# Ограничение для кошелька: нельзя оплатить больше чем к оплате
|
||||
if payment_method.code == 'account_balance' and amount > order.amount_due:
|
||||
raise ValidationError(
|
||||
f'Сумма оплаты из кошелька ({amount} руб.) не может превышать '
|
||||
f'остаток к оплате ({order.amount_due} руб.)'
|
||||
)
|
||||
|
||||
# Создаём транзакцию
|
||||
txn = Transaction.objects.create(
|
||||
order=order,
|
||||
|
||||
Reference in New Issue
Block a user