57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
"""Pure rules for TBank payment notification handling."""
|
|
|
|
from enum import Enum
|
|
|
|
|
|
class TBankPaymentNotificationAction(str, Enum):
|
|
ACKNOWLEDGE_ONLY = "acknowledge_only"
|
|
REGISTER_PROVIDER_ORDER = "register_provider_order"
|
|
|
|
|
|
def resolve_tbank_payment_notification_action(
|
|
*,
|
|
status: str,
|
|
success: bool,
|
|
error_code: str,
|
|
) -> TBankPaymentNotificationAction:
|
|
if status == "CONFIRMED" and success is True and error_code == "0":
|
|
return TBankPaymentNotificationAction.REGISTER_PROVIDER_ORDER
|
|
return TBankPaymentNotificationAction.ACKNOWLEDGE_ONLY
|
|
|
|
|
|
# Монотонный приоритет статусов платежа TBank по жизненному циклу.
|
|
# Используется, чтобы внеочередное уведомление не понижало уже записанный статус
|
|
# (например, AUTHORIZED, пришедший после CONFIRMED, не должен затирать CONFIRMED).
|
|
# Неизвестные статусы получают ранг 0 и не перезаписывают известный статус.
|
|
_TBANK_PAYMENT_STATUS_RANK: dict[str, int] = {
|
|
"NEW": 10,
|
|
"FORM_SHOWED": 20,
|
|
"AUTHORIZING": 30,
|
|
"3DS_CHECKING": 30,
|
|
"3DS_CHECKED": 30,
|
|
"REJECTED": 40,
|
|
"AUTH_FAIL": 40,
|
|
"DEADLINE_EXPIRED": 40,
|
|
"AUTHORIZED": 40,
|
|
"CONFIRMING": 50,
|
|
"CONFIRMED": 60,
|
|
"REVERSING": 70,
|
|
"PARTIAL_REVERSED": 70,
|
|
"REVERSED": 70,
|
|
"REFUNDING": 70,
|
|
"PARTIAL_REFUNDED": 70,
|
|
"REFUNDED": 70,
|
|
"CANCELED": 70,
|
|
}
|
|
|
|
|
|
def tbank_payment_status_rank(status: str) -> int:
|
|
return _TBANK_PAYMENT_STATUS_RANK.get(status, 0)
|
|
|
|
|
|
def should_apply_tbank_payment_status(current: str | None, new: str) -> bool:
|
|
"""Применять новый статус, только если он не понижает текущий по жизненному циклу."""
|
|
if current is None:
|
|
return True
|
|
return tbank_payment_status_rank(new) >= tbank_payment_status_rank(current)
|