Исходный код tbank.business.models
from __future__ import annotations
import uuid
from datetime import date, datetime
from decimal import Decimal
from typing import Annotated, Any, Dict, List, Optional
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer
from pydantic.alias_generators import to_camel
from tbank.business.enums import (
AccountType,
InvoiceStatus,
InvoiceVat,
OperationStatus,
PaymentStatus,
SbpQrStatus,
SbpQrType,
SbpVat,
TypeOfOperation,
)
from tbank.core.models import Rubles
# Суммы на запись: Decimal у пользователя, но в JSON уходит числом (T-API ждёт number).
WriteRubles = Annotated[
Decimal, PlainSerializer(lambda v: float(v), return_type=float, when_used="json")
]
[документация]
class BusinessModel(BaseModel):
"""Базовая модель T-API: snake_case в Python, camelCase на проводе."""
model_config = ConfigDict(
alias_generator=to_camel,
populate_by_name=True,
extra="ignore",
)
# --- Счета ---
[документация]
class Balance(BusinessModel):
otb: Optional[Rubles] = None # доступный остаток
authorized: Optional[Rubles] = None # заблокировано (холды)
pending_payments: Optional[Rubles] = None
pending_requisitions: Optional[Rubles] = None
[документация]
class TransitAccount(BusinessModel):
account_number: Optional[str] = None
[документация]
class Account(BusinessModel):
account_number: str
name: str
currency: str # числовой код ОКВ, напр. "643"
bank_bik: str
account_type: AccountType
balance: Optional[Balance] = None
transit_account: Optional[TransitAccount] = None
# --- Выписка (statement, курсорная пагинация) ---
[документация]
class StatementParams(BusinessModel):
account_number: str
from_: datetime = Field(alias="from") # включительно
to: Optional[datetime] = None # не включительно
cursor: Optional[str] = None
limit: Optional[int] = None
with_balances: Optional[bool] = None
operation_status: Optional[OperationStatus] = None
[документация]
class Counterparty(BusinessModel):
account: Optional[str] = None
inn: Optional[str] = None
kpp: Optional[str] = None
name: Optional[str] = None
bank_name: Optional[str] = None
bic_ru: Optional[str] = None
[документация]
class StatementOperation(BusinessModel):
operation_id: str
operation_date: datetime
operation_status: Optional[OperationStatus] = None
type_of_operation: Optional[TypeOfOperation] = None
category: Optional[str] = None
operation_amount: Optional[Rubles] = None
account_amount: Optional[Rubles] = None
ruble_amount: Optional[Rubles] = None
pay_purpose: Optional[str] = None
payer: Optional[Counterparty] = None
receiver: Optional[Counterparty] = None
counter_party: Optional[Counterparty] = None
[документация]
class StatementBalances(BusinessModel):
balance_begin: Optional[Rubles] = None
balance_end: Optional[Rubles] = None
credit: Optional[Rubles] = None
debit: Optional[Rubles] = None
[документация]
class StatementPage(BusinessModel):
balances: Optional[StatementBalances] = None
operations: List[StatementOperation] = Field(default_factory=list)
next_cursor: Optional[str] = None
# --- Выписка за период (bank-statement) ---
[документация]
class BankStatementParams(BusinessModel):
account_number: str
from_: Optional[date] = Field(default=None, alias="from")
till: Optional[date] = None
[документация]
class BankStatementOperation(BusinessModel):
id: Optional[str] = None
date: Optional[date] = None
amount: Optional[Rubles] = None
payment_purpose: Optional[str] = None
payer_name: Optional[str] = None
payer_inn: Optional[str] = None
payer_kpp: Optional[str] = None
recipient_name: Optional[str] = None
recipient_inn: Optional[str] = None
recipient_kpp: Optional[str] = None
[документация]
class BankStatement(BusinessModel):
saldo_in: Optional[Rubles] = None
income: Optional[Rubles] = None
outcome: Optional[Rubles] = None
saldo_out: Optional[Rubles] = None
operation: List[BankStatementOperation] = Field(default_factory=list)
# --- Платежи (рублёвая платёжка, mTLS) ---
[документация]
class ReceiverRequisites(BusinessModel):
name: str
inn: str
account_number: str
bik: str
kpp: Optional[str] = None
bank_name: Optional[str] = None
corr_account_number: Optional[str] = None
[документация]
class ThirdParty(BusinessModel):
inn: str
kpp: str
name: Optional[str] = None
[документация]
class TaxPaymentParameters(BusinessModel):
payer_status: str
kbk: str
oktmo: str
evidence: str
period: str # формат ДД.ММ.ГГГГ (строка, НЕ дата)
doc_number: str
doc_date: str # формат ДД.ММ.ГГГГ
third_party: Optional[ThirdParty] = None
[документация]
class CreatePaymentRequest(BusinessModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4())) # ключ идемпотентности
from_: PaymentFrom = Field(alias="from")
to: ReceiverRequisites
purpose: str
amount: WriteRubles
document_number: Optional[int] = None
execution_order: Optional[int] = None
due_date: Optional[datetime] = None
uin: Optional[str] = None
tax: Optional[TaxPaymentParameters] = None
revenue_type_code: Optional[str] = None
meta: Optional[Dict[str, Any]] = None
[документация]
class PaymentStatusResponse(BusinessModel):
status: PaymentStatus
error_message: Optional[str] = None
meta: Optional[Dict[str, Any]] = None
[документация]
class DocumentsStatusRequest(BusinessModel):
document_ids: List[str]
[документация]
class DocumentStatus(BusinessModel):
document_id: Optional[str] = None
status: Optional[str] = None
[документация]
class DocumentStatusError(BusinessModel):
document_id: Optional[str] = None
error_message: Optional[str] = None
[документация]
class DocumentsStatusResponse(BusinessModel):
result: List[DocumentStatus] = Field(default_factory=list)
result_error: List[DocumentStatusError] = Field(default_factory=list)
# --- Выставление счетов (инвойсы) ---
[документация]
class InvoicePayer(BusinessModel):
name: Optional[str] = None
inn: Optional[str] = None
kpp: Optional[str] = None
[документация]
class InvoiceItem(BusinessModel):
name: str
price: WriteRubles # цена за единицу в рублях
unit: str # единица измерения, напр. "Шт"
vat: InvoiceVat
amount: WriteRubles # количество единиц
[документация]
class SendInvoiceRequest(BusinessModel):
invoice_number: str
due_date: Optional[date] = None # YYYY-MM-DD
invoice_date: Optional[date] = None
account_number: Optional[str] = None
payer: Optional[InvoicePayer] = None
items: Optional[List[InvoiceItem]] = None
contacts: Optional[List[InvoiceContact]] = None
contact_phone: Optional[str] = None
comment: Optional[str] = None
custom_payment_purpose: Optional[str] = None
[документация]
class SendInvoiceResponse(BusinessModel):
pdf_url: str
invoice_id: str
incoming_invoice_url: Optional[str] = None
[документация]
class InvoiceInfo(BusinessModel):
status: InvoiceStatus
# --- Выставление ссылок через СБП (b2b QR) ---
[документация]
class CreateOnetimeQrRequest(BusinessModel):
sum: WriteRubles
purpose: str
ttl: int # срок жизни ссылки в днях
account_number: Optional[str] = None
vat: Optional[SbpVat] = None
redirect_url: Optional[str] = None
[документация]
class CreateReusableQrRequest(BusinessModel):
account_number: Optional[str] = None
sum: Optional[WriteRubles] = None # 10..999999
purpose: Optional[str] = None
vat: Optional[SbpVat] = None
redirect_url: Optional[str] = None
[документация]
class SbpQrImage(BusinessModel):
content: Optional[str] = None # base64
media_type: Optional[str] = None
[документация]
class SbpQrResponse(BusinessModel):
qr_id: str
payment_url: str
type: SbpQrType
status: SbpQrStatus
account_number: str
vat: Optional[SbpVat] = None
sum: Optional[Rubles] = None
sum_vat: Optional[Rubles] = None
due_date: Optional[datetime] = None # ISO date-time
purpose: Optional[str] = None
redirect_url: Optional[str] = None
image: Optional[SbpQrImage] = None