ВЭД — валютный контроль (tbank.ved)¶
Постановка валютного контракта на учёт, внесение изменений, снятие с учёта и проверка статуса заявления.
Хосты: постановка/изменение/снятие — на
secured-openapi.tbank.ru(mTLS,cert) и требуют криптоподписи запроса; статус заявления — наbusiness.tbank.ru/openapiпо Bearer.Подпись: схема HTTP Signatures (HMAC-SHA256).
keyIdи секрет выдаёт менеджер Т-Банка. Передаётся в клиент какsignature=CurrencySignature(key_id, secret).Суммы:
Decimal. Провод:camelCase; целочисленные перечисления (ContractSubject,ContractTypeи др.) уходят числами.Клиенты:
tbank.ved.VedClient(async) иtbank.ved.sync.VedClient(sync).
Предупреждение
Точная сборка строки подписи в OpenAPI-спеке приведена не полностью (без примера).
CurrencySignature реализует стандарт draft-cavage: строка подписи — это
построчное объединение подписываемых заголовков ((request-target), date,
data). Перед боевым использованием сверьте подпись с реальным ключом.
from decimal import Decimal
from tbank.ved import VedClient, CurrencySignature
from tbank.ved.models import RegisterContractRequest, ContractInfo, Counterparty
from tbank.ved.enums import ContractSubject, ContractType
client = VedClient(
token="business-token",
cert=("client.pem", "client-key.pem"), # mTLS
signature=CurrencySignature("key-id", "secret"), # выдаёт менеджер
)
# поставить контракт на учёт
res = await client.register_contract(RegisterContractRequest(
open_api_application_id="APP-1",
contract_info=ContractInfo(
contract_subject=ContractSubject.GOODS,
contract_type=ContractType.EXPORT,
currency_code="840",
contract_date="2026-01-10",
exchange_rate_effective_date="2026-01-10",
amount=Decimal("100000"),
counterparty=[Counterparty(name="ACME Inc", country_code="840")],
),
))
# проверить статус заявления (Bearer, без подписи)
status = await client.get_application_status(res.open_api_application_id)
print(status.status, status.metadata.unique_contract_number)
Изменение и снятие с учёта — amend_contract и deregister_contract.
Клиент¶
- class tbank.ved.aio.VedClient(token, *, signature=None, base_url=None, secured_base_url=None, sandbox=False, cert=None, verify=True, retry=None, transport=None, secured_transport=None)[исходный код]¶
Базовые классы:
BaseAsyncClientАсинхронный клиент ВЭД (валютный контроль): постановка контракта на учёт, изменение, снятие с учёта и статус заявления.
Постановка/изменение/снятие идут на secured-хост (mTLS, cert) и требуют криптоподписи запроса (signature — CurrencySignature(keyId, secret)); статус заявления — на обычном хосте по Bearer. Провод — camelCase.
- Параметры:
token (str)
signature (Optional[CurrencySignature])
base_url (Optional[str])
secured_base_url (Optional[str])
sandbox (bool)
cert (Optional[CertTypes])
verify (VerifyTypes)
retry (Optional[RetryPolicy])
transport (Optional[AsyncTransport])
secured_transport (Optional[AsyncTransport])
- async register_contract(request)[исходный код]¶
Поставить валютный контракт на учёт (mTLS + подпись).
- Параметры:
request (RegisterContractRequest)
- Тип результата:
- async amend_contract(request)[исходный код]¶
Внести изменения в валютный контракт (mTLS + подпись).
- Параметры:
request (AmendContractRequest)
- Тип результата:
- async deregister_contract(request)[исходный код]¶
Снять валютный контракт с учёта (mTLS + подпись).
- Параметры:
request (DeregisterContractRequest)
- Тип результата:
- async get_application_status(application_id)[исходный код]¶
Статус заявления по валютному контракту.
- Параметры:
application_id (str)
- Тип результата:
Подпись¶
- tbank.ved.signing.CurrencySignature¶
псевдоним для
HttpSignature
Модели¶
- class tbank.ved.models.VedModel[исходный код]¶
Базовые классы:
BaseModelБазовая модель домена: snake_case в Python, camelCase на проводе.
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.Attachment(*, documentId, documentName=None, version=None)[исходный код]¶
Базовые классы:
VedModel- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.Counterparty(*, name, countryCode, signAffiliation=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
name (str)
countryCode (str)
signAffiliation (SignAffiliation | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ResidentInfo(*, inn, kpp=None)[исходный код]¶
Базовые классы:
VedModel- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ContractInfo(*, contractSubject, currencyCode, contractDate, exchangeRateEffectiveDate, contractType=None, supply=None, estateType=None, amount=None, liabilitiesFinishDate=None, contractNumber=None, attachments=None, counterparty=None)[исходный код]¶
Базовые классы:
VedModelСведения о валютном контракте для постановки на учёт.
- Параметры:
contractSubject (ContractSubject)
currencyCode (str)
contractDate (date)
exchangeRateEffectiveDate (date)
contractType (ContractType | None)
supply (Supply | None)
estateType (EstateType | None)
amount (Annotated[Decimal, PlainSerializer(func=~tbank.ved.models.<lambda>, return_type=float, when_used=json)] | None)
liabilitiesFinishDate (date | None)
contractNumber (str | None)
attachments (List[Attachment] | None)
counterparty (List[Counterparty] | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.RegisterContractRequest(*, openApiApplicationId, contractInfo, residentInfo=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
openApiApplicationId (str)
contractInfo (ContractInfo)
residentInfo (ResidentInfo | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ApplicationResult(*, openApiApplicationId)[исходный код]¶
Базовые классы:
VedModelОтвет на регистрацию/изменение/снятие контракта.
- Параметры:
openApiApplicationId (str)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.AmendmentDocument(*, documentDate, attachments, documentNumber=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
documentDate (date)
attachments (List[Attachment])
documentNumber (str | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.AmendContractRequest(*, openApiApplicationId, uniqueContractNumber, amendments, amendmentDocuments=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ChangeDocument(*, documentDate, documentNumber=None)[исходный код]¶
Базовые классы:
VedModel- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.AssignmentResidentInfo(*, name, ogrn, ogrnDate, inn, kpp=None, changeDocument=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.AssignmentNonResidentInfo(*, name, countryCode, changeDocument=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
name (str)
countryCode (str)
changeDocument (ChangeDocument | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.DeregisterContractRequest(*, openApiApplicationId, uniqueContractNumber, deregistrationReason, attachments=None, assignmentResidentInfo=None, assignmentNonResidentInfo=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
openApiApplicationId (str)
uniqueContractNumber (str)
deregistrationReason (int)
attachments (List[Attachment] | None)
assignmentResidentInfo (AssignmentResidentInfo | None)
assignmentNonResidentInfo (AssignmentNonResidentInfo | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ApplicationStatusMetadata(*, uniqueContractNumber=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
uniqueContractNumber (str | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tbank.ved.models.ApplicationStatusInfo(*, openApiApplicationId, status, datetime, metadata, description=None)[исходный код]¶
Базовые классы:
VedModel- Параметры:
openApiApplicationId (str)
status (ApplicationStatus)
datetime (datetime)
metadata (ApplicationStatusMetadata)
description (str | None)
- model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Перечисления¶
- class tbank.ved.enums.ContractSubject(*values)[исходный код]¶
Базовые классы:
IntEnumПредмет валютного контракта.
- GOODS = 0¶
- SERVICES = 1¶
- GOODS_AND_SERVICES = 2¶
- CREDITS_AND_LEASING = 3¶
- ESTATE_SALE = 4¶
- INVESTMENTS = 5¶
- NON_FINANCIAL = 6¶
- class tbank.ved.enums.ContractType(*values)[исходный код]¶
Базовые классы:
IntEnumТип валютного контракта.
- EXPORT = 0¶
- IMPORT = 1¶
- MIXED = 2¶
- class tbank.ved.enums.Supply(*values)[исходный код]¶
Базовые классы:
IntEnumУсловие поставки товара.
- CROSSES_BORDER = 0¶
- TRANSIT = 1¶
- NO_BORDER = 2¶
- class tbank.ved.enums.EstateType(*values)[исходный код]¶
Базовые классы:
IntEnumТип недвижимости в контракте.
- ESTATE = 0¶
- VESSELS = 1¶
- class tbank.ved.enums.SignAffiliation(*values)[исходный код]¶
-
Признак аффилированности контрагента.
- YES = 'YES'¶
- NO = 'NO'¶