Добавлен адаптер к tbank и формирование ссылки на оплату

This commit is contained in:
Раис Юсупалиев
2026-04-12 18:56:41 +03:00
parent ab0b66e1c2
commit 2b201a08be
34 changed files with 1322 additions and 268 deletions
+32 -28
View File
@@ -13,6 +13,10 @@ from app.adapters.address_suggestions.base import (
AddressSuggestionRequestError,
)
from app.adapters.delivery_providers.base import DeliveryProvider, ProviderRequestError
from app.adapters.tbank.base import (
TBankPaymentAdapterError,
TBankPaymentRequestError,
)
from app.domain.price import (
DEFAULT_PROVIDER_PRICE_MULTIPLIER,
DEFAULT_WEIGHT_ROUND_SCALE,
@@ -20,7 +24,7 @@ from app.domain.price import (
filter_and_sort_prices,
normalize_delivery_request,
)
from app.schemas.order import OrderCreateRequest, OrderCreateResponse
from app.schemas.payment import InitPaymentRequest, InitPaymentResponse
from app.schemas.request import AddressSuggestRequest, DeliveryCalculationRequest
from app.schemas.response import AddressSuggestion, DeliveryPrice
@@ -45,12 +49,12 @@ class AddressSuggestionsUnavailableError(AggregatorServiceError):
"""Raised when address suggestions cannot be completed."""
class InvalidOrderCreateRequestError(AggregatorServiceError):
"""Raised when provider rejects order creation payload as invalid."""
class InvalidInitPaymentRequestError(AggregatorServiceError):
"""Raised when provider rejects payment init payload as invalid."""
class OrderCreationUnavailableError(AggregatorServiceError):
"""Raised when order creation cannot be completed."""
class InitPaymentUnavailableError(AggregatorServiceError):
"""Raised when payment initialization cannot be completed."""
class PriceCacheProtocol(Protocol):
@@ -59,6 +63,10 @@ class PriceCacheProtocol(Protocol):
async def set(self, key: str, value: object, ttl: int | None = None) -> None: ...
class PaymentAdapterProtocol(Protocol):
async def create_payment_link(self, order_uuid: str, amount_kopecks: int) -> str: ...
class FilterAndSortPricesFn(Protocol):
def __call__(
self,
@@ -69,18 +77,12 @@ class FilterAndSortPricesFn(Protocol):
) -> list[object]: ...
class OrderRegistrationAdapterProtocol(Protocol):
async def register_order(
self, request: OrderCreateRequest
) -> OrderCreateResponse: ...
class AggregatorService:
def __init__(
self,
providers: Sequence[DeliveryProvider],
cache: PriceCacheProtocol | None = None,
order_adapter: OrderRegistrationAdapterProtocol | None = None,
payment_adapter: PaymentAdapterProtocol | None = None,
address_suggestion_providers: Sequence[AddressSuggestionProvider] = (),
address_suggestion_country_to_provider: Mapping[str, str] | None = None,
*,
@@ -90,7 +92,7 @@ class AggregatorService:
) -> None:
self._providers = tuple(providers)
self._cache = cache
self._order_adapter = order_adapter
self._payment_adapter = payment_adapter
self._weight_round_scale = weight_round_scale
self._provider_price_multiplier = provider_price_multiplier
self._filter_and_sort_prices = filter_and_sort_prices_fn
@@ -168,27 +170,29 @@ class AggregatorService:
return [self._coerce_address_suggestion(item) for item in suggestions]
async def create_order(self, request: OrderCreateRequest) -> OrderCreateResponse:
if self._order_adapter is None:
raise OrderCreationUnavailableError(
"Order registration adapter is not configured."
)
async def init_payment(self, request: InitPaymentRequest) -> InitPaymentResponse:
if self._payment_adapter is None:
raise InitPaymentUnavailableError("Payment adapter is not configured.")
try:
created_order = await self._order_adapter.register_order(request)
except ProviderRequestError as exc:
raise InvalidOrderCreateRequestError(
"Order request is invalid for the configured provider."
payment_url = await self._payment_adapter.create_payment_link(
order_uuid=request.order_uuid,
amount_kopecks=request.price,
)
except TBankPaymentRequestError as exc:
raise InvalidInitPaymentRequestError(
"Payment init request is invalid for the configured provider."
) from exc
except TBankPaymentAdapterError as exc:
raise InitPaymentUnavailableError(
"Payment initialization is temporarily unavailable."
) from exc
except Exception as exc:
raise OrderCreationUnavailableError(
"Order creation is temporarily unavailable."
raise InitPaymentUnavailableError(
"Payment initialization is temporarily unavailable."
) from exc
return OrderCreateResponse.model_validate(
created_order,
from_attributes=True,
)
return InitPaymentResponse(payment_url=payment_url)
async def _get_provider_prices(
self,