ВЭД — валютный контроль (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) и требуют криптоподписи запроса (signatureCurrencySignature(keyId, secret)); статус заявления — на обычном хосте по Bearer. Провод — camelCase.

Параметры:
async register_contract(request)[исходный код]

Поставить валютный контракт на учёт (mTLS + подпись).

Параметры:

request (RegisterContractRequest)

Тип результата:

ApplicationResult

async amend_contract(request)[исходный код]

Внести изменения в валютный контракт (mTLS + подпись).

Параметры:

request (AmendContractRequest)

Тип результата:

ApplicationResult

async deregister_contract(request)[исходный код]

Снять валютный контракт с учёта (mTLS + подпись).

Параметры:

request (DeregisterContractRequest)

Тип результата:

ApplicationResult

async get_application_status(application_id)[исходный код]

Статус заявления по валютному контракту.

Параметры:

application_id (str)

Тип результата:

ApplicationStatusInfo

Подпись

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

Параметры:
  • documentId (int | str)

  • documentName (str | None)

  • version (int | 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.Counterparty(*, name, countryCode, signAffiliation=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.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

Сведения о валютном контракте для постановки на учёт.

Параметры:
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

Параметры:
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

Параметры:
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

Параметры:
  • documentDate (date)

  • 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.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

Параметры:
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

Параметры:
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

Параметры:
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)[исходный код]

Базовые классы: str, Enum

Признак аффилированности контрагента.

YES = 'YES'
NO = 'NO'
class tbank.ved.enums.ApplicationStatus(*values)[исходный код]

Базовые классы: str, Enum

Статус заявления по валютному контракту.

APPROVED = 'APPROVED'
DECLINED = 'DECLINED'
SUBMITTED = 'SUBMITTED'