Безакцептные списания (tbank.direct_debit)

Списание средств со счёта плательщика по заранее подписанному соглашению — без подтверждения каждой операции. SDK покрывает три сущности: соглашения (основа для списаний), правила (рекуррентные — по расписанию cron, и триггерные — по факту пополнения) и платёжные требования (разовые списания/пополнения).

  • Хост: весь домен работает на secured-openapi.tbank.ru и требует mTLS-сертификата (cert).

  • Идемпотентность: создание правил/требований и отзыв требования принимают idempotency_key (по умолчанию генерируется автоматически).

  • Суммы: Decimal в рублях. Провод: camelCase.

  • Клиенты: tbank.direct_debit.DirectDebitClient (async) и tbank.direct_debit.sync.DirectDebitClient (sync).

Соглашения

from tbank.direct_debit import DirectDebitClient

client = DirectDebitClient(
    token="business-token",
    cert=("client.pem", "client-key.pem"),   # mTLS обязателен
)

# ссылка на подписание соглашения контрагентом
url = await client.get_agreement_url()

# список и карточка соглашений
agreements = await client.list_agreements()
agreement = await client.get_agreement(agreements.results[0].id)
pdf = await client.get_agreement_file(agreement.id)   # content — base64 PDF

Правила

from decimal import Decimal
from tbank.direct_debit.models import (
    RecurrentRuleCreate, TriggerRuleCreate, PaymentRequisites,
    TriggerAmount, ReplenishmentFilter,
)

requisites = PaymentRequisites(
    payer_account="40817810000000000001", payer_name="ООО Ромашка",
    payer_inn="1234567890", payer_kpp="0", payer_bic="044525225",
    payer_cor_account="30101810000000000225",
    recipient_account="40702810000000000000", purpose="Абонентская плата",
    amount=Decimal("1500.00"),
)

# рекуррентное правило — списание по расписанию
await client.create_rule(RecurrentRuleCreate(
    agreement_id=agreement.id, cron_expr="0 12 1 * *", requisites=requisites,
))

# триггерное правило — списание процента от каждого пополнения
await client.create_rule(TriggerRuleCreate(
    agreement_id=agreement.id,
    amount=TriggerAmount(percent=Decimal("0.1")),      # 10%
    replenishment_filter=ReplenishmentFilter(category="MerchantAcq"),
    requisites=requisites,
))

# список (v2 — с полной карточкой), обновление, удаление
rules = await client.list_rules_v2(agreement_id=agreement.id)
rule = await client.get_rule(rules.results[0].id)
await client.delete_rule(rule.id)

get_rule/update_rule возвращают RecurrentRuleDetails либо TriggerRuleDetails — SDK разбирает ответ по полю type.

Платёжные требования

from tbank.direct_debit.models import CreatePaymentRequest

req = await client.create_payment_request(CreatePaymentRequest(
    payer_account="40817810000000000001", payer_name="ООО Ромашка",
    payer_inn="1234567890", payer_kpp="0", payer_bic="044525225",
    payer_cor_account="30101810000000000225",
    recipient_account="40702810000000000000", purpose="Оплата по счёту №5",
    amount=Decimal("10000.00"),
))

await client.list_payment_requests(start_date="2026-01-01", end_date="2026-06-30")
details = await client.get_payment_request(req.id)
pdf = await client.get_payment_request_file(req.id)    # content — base64 PDF
await client.revoke_payment_request(req.id)            # отозвать

Клиент

class tbank.direct_debit.aio.DirectDebitClient(token, *, base_url=None, sandbox=False, cert=None, verify=True, retry=None, transport=None)[исходный код]

Базовые классы: BaseAsyncClient

Асинхронный клиент безакцептных списаний: соглашения, правила (рекуррентные и триггерные) и платёжные требования.

Весь домен работает на secured-хосте и требует mTLS-сертификата (cert). Методы создания принимают ключ идемпотентности idempotency_key (по умолчанию генерируется автоматически). Суммы — Decimal в рублях, провод — camelCase.

Параметры:
decimal_body: ClassVar[bool] = True

True → тело парсится с parse_float=Decimal (точные денежные суммы).

async list_rules(agreement_id, *, offset=None, limit=None)[исходный код]

Список правил соглашения.

Параметры:
  • agreement_id (str)

  • offset (int | None)

  • limit (int | None)

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

RuleListResponse

async list_rules_v2(*, agreement_id=None, rule_types=None, offset=None, limit=None)[исходный код]

Список правил с полной карточкой (v2).

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

RuleDetailsListResponse

async create_rule(rule, *, idempotency_key=None)[исходный код]

Создать правило (рекуррентное или триггерное).

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

CreateRuleResult

async get_rule(rule_id)[исходный код]

Карточка правила.

Параметры:

rule_id (str)

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

Annotated[RecurrentRuleDetails | TriggerRuleDetails, FieldInfo(annotation=NoneType, required=True, discriminator=“type“)]

async update_rule(rule_id, rule)[исходный код]

Обновить правило.

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

Annotated[RecurrentRuleDetails | TriggerRuleDetails, FieldInfo(annotation=NoneType, required=True, discriminator=“type“)]

async delete_rule(rule_id)[исходный код]

Удалить правило.

Параметры:

rule_id (str)

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

None

async list_payment_requests(*, start_date=None, end_date=None, offset=None, limit=None)[исходный код]

Список платёжных требований за период (YYYY-MM-DD).

Параметры:
  • start_date (str | None)

  • end_date (str | None)

  • offset (int | None)

  • limit (int | None)

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

PaymentRequestListResponse

async create_payment_request(request, *, idempotency_key=None)[исходный код]

Создать платёжное требование.

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

CreatePaymentRequestResult

async get_payment_request(request_id)[исходный код]

Карточка платёжного требования.

Параметры:

request_id (str)

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

PaymentRequestDetails

async revoke_payment_request(request_id, *, idempotency_key=None)[исходный код]

Отозвать платёжное требование.

Параметры:
  • request_id (str)

  • idempotency_key (str | None)

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

None

async get_payment_request_file(request_id)[исходный код]

PDF платёжного требования (base64).

Параметры:

request_id (str)

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

PaymentRequestFile

async list_agreements(*, offset=None, limit=None)[исходный код]

Список соглашений о безакцептном списании.

Параметры:
  • offset (int | None)

  • limit (int | None)

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

AgreementListResponse

async get_agreement(agreement_id)[исходный код]

Карточка соглашения.

Параметры:

agreement_id (str)

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

AgreementDetails

async get_agreement_file(agreement_id)[исходный код]

PDF-файл соглашения (base64).

Параметры:

agreement_id (str)

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

AgreementFile

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

Ссылка на форму подписания соглашения для контрагента.

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

AgreementUrl

Модели

class tbank.direct_debit.models.DirectDebitModel[исходный код]

Базовые классы: 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.direct_debit.models.PaymentRequisites(*, payerAccount, payerName, payerINN, payerKPP, payerBIC, payerCorAccount, recipientAccount, purpose, docType=DocType.PAYMENT_REQUEST, amount=None, paymentCondition=None, acceptTerm=None, docDispatchDate=None)[исходный код]

Базовые классы: DirectDebitModel

Реквизиты платёжного требования (списание/пополнение).

Параметры:
  • payerAccount (str)

  • payerName (str)

  • payerINN (str)

  • payerKPP (str)

  • payerBIC (str)

  • payerCorAccount (str)

  • recipientAccount (str)

  • purpose (str)

  • docType (DocType)

  • amount (Annotated[Decimal, PlainSerializer(func=~tbank.direct_debit.models.<lambda>, return_type=float, when_used=json)] | None)

  • paymentCondition (PaymentCondition | None)

  • acceptTerm (int | None)

  • docDispatchDate (date | 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.direct_debit.models.CreatePaymentRequest(*, payerAccount, payerName, payerINN, payerKPP, payerBIC, payerCorAccount, recipientAccount, purpose, docType=DocType.PAYMENT_REQUEST, amount=None, paymentCondition=None, acceptTerm=None, docDispatchDate=None, documentNumber=None, agreementId=None)[исходный код]

Базовые классы: PaymentRequisites

Тело создания платёжного требования (POST /requests).

Параметры:
  • payerAccount (str)

  • payerName (str)

  • payerINN (str)

  • payerKPP (str)

  • payerBIC (str)

  • payerCorAccount (str)

  • recipientAccount (str)

  • purpose (str)

  • docType (DocType)

  • amount (Annotated[Decimal, PlainSerializer(func=~tbank.direct_debit.models.<lambda>, return_type=float, when_used=json)] | None)

  • paymentCondition (PaymentCondition | None)

  • acceptTerm (int | None)

  • docDispatchDate (date | None)

  • documentNumber (int | None)

  • agreementId (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.direct_debit.models.TriggerAmount(*, fixed=None, percent=None)[исходный код]

Базовые классы: DirectDebitModel

Сумма триггерного правила: фиксированная или процент от пополнения.

Параметры:
  • fixed (Annotated[Decimal, PlainSerializer(func=~tbank.direct_debit.models.<lambda>, return_type=float, when_used=json)] | None)

  • percent (Annotated[Decimal, PlainSerializer(func=~tbank.direct_debit.models.<lambda>, return_type=float, when_used=json)] | 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.direct_debit.models.ReplenishmentPayer(*, inn, kpp)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.ReplenishmentFilter(*, category, payers=None)[исходный код]

Базовые классы: DirectDebitModel

Условия срабатывания триггерного правила по операциям пополнения.

Параметры:
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.direct_debit.models.RecurrentRuleCreate(*, type='Recurrent', agreementId, cronExpr, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.TriggerRuleCreate(*, type='Trigger', agreementId, amount, replenishmentFilter, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.RecurrentRuleUpdate(*, type='Recurrent', cronExpr, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.TriggerRuleUpdate(*, type='Trigger', amount, replenishmentFilter, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.RecurrentRuleDetails(*, type='Recurrent', id, agreementId, cronExpr, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.TriggerRuleDetails(*, type='Trigger', id, agreementId, amount, replenishmentFilter, requisites)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.RuleListItem(*, type, id, amount, cronExpr)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.RuleListResponse(*, offset, limit, size, total, results=None)[исходный код]

Базовые классы: _Paged

Параметры:
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.direct_debit.models.RuleDetailsListResponse(*, offset, limit, size, total, results=None)[исходный код]

Базовые классы: _Paged

Параметры:
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.direct_debit.models.CreateRuleResult(*, ruleId)[исходный код]

Базовые классы: DirectDebitModel

Параметры:

ruleId (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.direct_debit.models.PaymentRequestListItem(*, id, creationDate, docType, direction, status)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.PaymentRequestListResponse(*, offset, limit, size, total, results=None)[исходный код]

Базовые классы: _Paged

Параметры:
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.direct_debit.models.PaymentRequestDetails(*, id, creationDate, docType, amount, payerAccount, payerName, payerINN, recipientAccount, purpose, direction, status, payerKPP=None, payerBIC=None, payerCorAccount=None, paymentCondition=None, acceptTerm=None, docDispatchDate=None, documentNumber=None, agreementId=None, ruleId=None)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.CreatePaymentRequestResult(*, id)[исходный код]

Базовые классы: DirectDebitModel

Параметры:

id (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.direct_debit.models.PaymentRequestFile(*, content)[исходный код]

Базовые классы: DirectDebitModel

PDF платёжного требования (content — base64).

Параметры:

content (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.direct_debit.models.AgreementListItem(*, id, type=None, status=None)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.AgreementListResponse(*, offset, limit, size, total, results=None)[исходный код]

Базовые классы: _Paged

Параметры:
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.direct_debit.models.AgreementRequisites(*, name=None, address=None, inn=None, kpp=None, ogrn=None, signerName=None, signerPosition=None, signerDocument=None, accountNumber=None, accountCurrency=None, corAccountNumber=None, bic=None, bankName=None)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
  • name (str | None)

  • address (str | None)

  • inn (str | None)

  • kpp (str | None)

  • ogrn (str | None)

  • signerName (str | None)

  • signerPosition (str | None)

  • signerDocument (str | None)

  • accountNumber (str | None)

  • accountCurrency (str | None)

  • corAccountNumber (str | None)

  • bic (str | None)

  • bankName (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.direct_debit.models.AgreementDetails(*, id, number, recipientRequisites, payerRequisites, startDate, endDate=None, maxSum=None, currency=None, reason=None, status=None)[исходный код]

Базовые классы: DirectDebitModel

Параметры:
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.direct_debit.models.AgreementFile(*, filename, content)[исходный код]

Базовые классы: DirectDebitModel

PDF соглашения (content — base64).

Параметры:
  • filename (str)

  • content (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.direct_debit.models.AgreementUrl(*, url)[исходный код]

Базовые классы: DirectDebitModel

Параметры:

url (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.direct_debit.enums.RuleType(*values)[исходный код]

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

Тип правила безакцептного списания.

RECURRENT = 'Recurrent'
TRIGGER = 'Trigger'
class tbank.direct_debit.enums.DocType(*values)[исходный код]

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

Тип платёжного документа.

PAYMENT_REQUEST = 'PaymentRequest'
class tbank.direct_debit.enums.PaymentCondition(*values)[исходный код]

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

Условие платежа.

WITH_ACCEPTANCE = 'WithAcceptance'
WITHOUT_ACCEPTANCE = 'WithoutAcceptance'
class tbank.direct_debit.enums.PaymentDirection(*values)[исходный код]

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

Направление платёжного требования.

DEBIT = 'Debit'
CREDIT = 'Credit'
class tbank.direct_debit.enums.PaymentRequestStatus(*values)[исходный код]

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

Статус платёжного требования.

PENDING = 'Pending'
SENT = 'Sent'
REVOKED = 'Revoked'
ARCHIVED = 'Archived'
ERROR = 'Error'
DECLINED = 'Declined'
CARD = 'Card'
ACCEPTED = 'Accepted'
OUTDATED = 'Outdated'
PARTIAL = 'Partial'
REVOKE_REQUESTED = 'RevokeRequested'
COMPLETED = 'Completed'
class tbank.direct_debit.enums.AgreementStatus(*values)[исходный код]

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

Статус соглашения о безакцептном списании.

PENDING = 'Pending'
ACTIVE = 'Active'
SIGNED = 'Signed'
TERMINATED = 'Terminated'
ERROR = 'Error'
OUTDATED = 'Outdated'
class tbank.direct_debit.enums.AgreementParticipant(*values)[исходный код]

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

Тип участия компании в соглашении.

RECIPIENT = 'Recipient'
PAYER = 'Payer'
class tbank.direct_debit.enums.ReplenishmentCategory(*values)[исходный код]

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

Категория операций пополнения для триггерного правила.

CASH_IN = 'CashIn'
MERCHANT_ACQ = 'MerchantAcq'
INTERNET_ACQ = 'InternetAcq'
COUNTERPARTY_INCOME = 'CounterpartyIncome'