Добавлена обработка уведомлений через ручку

This commit is contained in:
Раис Юсупалиев
2026-04-18 21:27:15 +03:00
parent 78e9ad4fa9
commit 6b66af5eb3
38 changed files with 1519 additions and 32 deletions
@@ -298,7 +298,7 @@ adapter:
tbank_payment:
init_url: "https://securepay.tinkoff.ru/v2/Init"
notification_url: "https://merchant.test/tbank/notification"
notification_url: "https://merchant.test/api/v1/delivery/tbank/notifications"
success_url: "https://merchant.test/payment/success"
auth:
terminal_key: "test-terminal-key"
@@ -119,6 +119,7 @@ def test_provider_register_order_posts_cdek_contract_payload_and_maps_response()
"method": "POST",
"url": "https://api.cdek.test/v2/orders",
"json": {
"number": "order-uuid-1",
"type": 2,
"tariff_code": 535,
"comment": "Test order",
@@ -245,6 +246,70 @@ def test_cdek_client_register_order_maps_4xx_to_request_error() -> None:
assert len(http_client.calls) == 1
def test_cdek_client_register_order_maps_duplicate_external_id_to_success() -> None:
duplicate_response = httpx.Response(
409,
json={
"entity": {"uuid": "existing-cdek-order-uuid"},
"requests": [
{
"errors": [
{
"code": "v2_entity_already_exists",
"message": "Order with this number already exists",
}
]
}
],
},
request=httpx.Request("POST", "https://api.cdek.test/v2/orders"),
)
http_client = SequenceHTTPClient([duplicate_response])
client = CDEKClient(
http_client=http_client, # type: ignore[arg-type]
auth_client=StubAuthClient(), # type: ignore[arg-type]
base_url="https://api.cdek.test/v2",
retry_attempts=2,
)
result = asyncio.run(client.register_order(_make_order_request()))
assert result == "existing-cdek-order-uuid"
assert len(http_client.calls) == 1
def test_cdek_client_register_order_4xx_with_unrelated_entity_uuid_raises_request_error() -> None:
unrelated_response = httpx.Response(
409,
json={
"entity": {"uuid": "unrelated-uuid"},
"requests": [
{
"errors": [
{
"code": "v2_recipient_phone_invalid",
"message": "Recipient phone is invalid",
}
]
}
],
},
request=httpx.Request("POST", "https://api.cdek.test/v2/orders"),
)
http_client = SequenceHTTPClient([unrelated_response])
client = CDEKClient(
http_client=http_client, # type: ignore[arg-type]
auth_client=StubAuthClient(), # type: ignore[arg-type]
base_url="https://api.cdek.test/v2",
retry_attempts=2,
)
with pytest.raises(CDEKRequestError):
asyncio.run(client.register_order(_make_order_request()))
assert len(http_client.calls) == 1
def test_cdek_client_register_order_retries_5xx_and_raises_client_error() -> None:
first_response = httpx.Response(
503,
@@ -0,0 +1,53 @@
from app.adapters.delivery_providers.cdek.order_mapper import (
map_cdek_order_request,
)
from app.schemas.payment import InitPaymentRequest
def _make_order_request(**overrides: object) -> InitPaymentRequest:
payload: dict[str, object] = {
"order_uuid": "order-uuid-1",
"price": 125000,
"type": 2,
"tariff_code": 535,
"comment": "Test order",
"sender": {
"name": "Petr Petrov",
"email": "sender@example.com",
"phone": {"number": "+79009876543"},
},
"recipient": {
"name": "Ivan Ivanov",
"email": "ivan@example.com",
"phone": {"number": "+79001234567"},
},
"from_location": {
"address": "Lenina 1",
"city": "Moscow",
"country_code": "RU",
},
"to_location": {
"address": "Pushkina 10",
"city": "Novosibirsk",
"country_code": "RU",
},
"services": [{"code": "INSURANCE", "parameter": "1000"}],
"packages": [
{
"number": "1",
"weight": 1,
"length": 20,
"width": 15,
"height": 10,
"comment": "Package 1",
}
],
}
payload.update(overrides)
return InitPaymentRequest(**payload)
def test_cdek_order_payload_uses_order_uuid_as_external_number() -> None:
payload = map_cdek_order_request(_make_order_request())
assert payload["number"] == "order-uuid-1"