feat(lk-contract): OpenAPI контракт lk-gateway по ESIA Finance API V1
- docs/lk-contract/v1/openapi.yaml — OpenAPI 3.0: POST/GET/PATCH /api/v1/back_office/claims, схемы Claim/CreateClaimRequest/StatusCallback/ErrorResponse - docs/lk-contract/v1/examples/claim-request.json — заявка с 3 ЦБ, ИИС T03 - docs/lk-contract/v1/examples/claim-response.json — ответ на создание - docs/lk-contract/v1/examples/callback-confirmed.json — callback подтверждения - docs/lk-contract/v1/examples/callback-rejected.json — callback отказа - docs/lk-contract/v1/examples/error-422.json — ошибка валидации - docs/lk-contract/v1/changelog.md — v1.0.0 Контракт предлагается команде реального ЛК как точка синхронизации. В lk-emulator (отдельный PR) контракт реализуется как «как-будто-ЛК» для проверки сквозного потока. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,656 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: lk-gateway API
|
||||
version: 1.0.0
|
||||
description: |
|
||||
REST-контракт между сервисом `lk-gateway` (Bridge-and-Join-s) и ЛК
|
||||
инвестора на платформе ESIA Finance. Версия V1 совместима с
|
||||
официальным API ESIA Finance (`DOC/API ЛК ЕСИА.pdf`).
|
||||
|
||||
Контракт обслуживает жизненный цикл заявки M2M-перевода: создание,
|
||||
получение, обновление статуса и список заявок.
|
||||
|
||||
Аутентификация — HTTP Basic. Кодировка — UTF-8. Тело запросов и
|
||||
ответов — JSON.
|
||||
servers:
|
||||
- url: https://lk-gateway.bridge-and-joins.local
|
||||
description: Production lk-gateway
|
||||
- url: http://localhost:8080
|
||||
description: Локальный эмулятор (lk-emulator)
|
||||
security:
|
||||
- basicAuth: []
|
||||
|
||||
paths:
|
||||
/api/v1/back_office/claims/:
|
||||
post:
|
||||
operationId: create_claim
|
||||
summary: Создать заявку на M2M-перевод
|
||||
description: |
|
||||
Принимает подписанное (XMLDSig) заявление инвестора. Сервис
|
||||
проверяет подпись через crypto-service, валидирует данные,
|
||||
создаёт сделку и инициирует отправку в НРД.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateClaimRequest'
|
||||
examples:
|
||||
full_claim:
|
||||
summary: Заявка с тремя ЦБ, ИИС T03
|
||||
externalValue: ./examples/claim-request.json
|
||||
responses:
|
||||
'201':
|
||||
description: Заявка создана
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateClaimResponse'
|
||||
'400':
|
||||
description: Невалидные входные данные
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'401':
|
||||
description: Не авторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'422':
|
||||
description: Подпись неверна или данные не прошли бизнес-валидацию
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/v1/back_office/claims:
|
||||
get:
|
||||
operationId: list_claims
|
||||
summary: Список заявок
|
||||
description: Возвращает список заявок с фильтрацией по статусу, периоду и инвестору.
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Фильтр по статусу.
|
||||
required: false
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClaimStatus'
|
||||
- name: investor_id
|
||||
in: query
|
||||
description: UUID инвестора в ЛК.
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: created_from
|
||||
in: query
|
||||
description: Нижняя граница периода создания (ISO 8601, UTC).
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- name: created_to
|
||||
in: query
|
||||
description: Верхняя граница периода создания (ISO 8601, UTC).
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 200
|
||||
default: 50
|
||||
- name: offset
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
responses:
|
||||
'200':
|
||||
description: Страница списка заявок
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClaimsPage'
|
||||
|
||||
/api/v1/back_office/claims/{id}:
|
||||
get:
|
||||
operationId: get_claim
|
||||
summary: Получить заявку и её статус
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: UUID заявки.
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Заявка
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Claim'
|
||||
'404':
|
||||
description: Заявка не найдена
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
patch:
|
||||
operationId: update_claim_status
|
||||
summary: Callback обновления статуса (от lk-gateway к ЛК)
|
||||
description: |
|
||||
Используется лгатвей-ом для уведомления ЛК о смене статуса
|
||||
сделки на стороне НРД. Подтверждение, отказ или таймаут.
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: UUID заявки.
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatusCallback'
|
||||
examples:
|
||||
confirmed:
|
||||
summary: Подтверждение
|
||||
externalValue: ./examples/callback-confirmed.json
|
||||
rejected:
|
||||
summary: Отказ
|
||||
externalValue: ./examples/callback-rejected.json
|
||||
responses:
|
||||
'200':
|
||||
description: Callback принят
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CallbackResponse'
|
||||
'404':
|
||||
description: Заявка не найдена
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
|
||||
schemas:
|
||||
ClaimStatus:
|
||||
type: string
|
||||
description: |
|
||||
Жизненный цикл заявки на M2M-перевод.
|
||||
- `draft` — черновик, ещё не подписан.
|
||||
- `signed` — подписан, но не отправлен.
|
||||
- `submitted` — отправлен в НРД.
|
||||
- `in_progress` — НРД принял, ждём решение от принимающей стороны.
|
||||
- `confirmed` — подтверждён, перевод исполнен.
|
||||
- `rejected` — отклонён.
|
||||
- `timed_out` — превышен SLA, ручной разбор.
|
||||
enum:
|
||||
- draft
|
||||
- signed
|
||||
- submitted
|
||||
- in_progress
|
||||
- confirmed
|
||||
- rejected
|
||||
- timed_out
|
||||
|
||||
SignatureFormat:
|
||||
type: string
|
||||
description: Тип цифровой подписи заявления.
|
||||
enum:
|
||||
- XMLDSig-GOST
|
||||
- XMLDSig-RSA
|
||||
|
||||
AgreementType:
|
||||
type: string
|
||||
description: |
|
||||
Тип договора ИИС.
|
||||
- `T12` — ИИС-1 или ИИС-2 (старый формат).
|
||||
- `T03` — ИИС-3 (новый).
|
||||
enum:
|
||||
- T12
|
||||
- T03
|
||||
|
||||
SecurityClassification:
|
||||
type: string
|
||||
description: Тип ценной бумаги.
|
||||
enum:
|
||||
- BOND
|
||||
- SHAR
|
||||
- MFUN
|
||||
|
||||
SecurityCategory:
|
||||
type: string
|
||||
description: Категория акций.
|
||||
enum:
|
||||
- ORDN
|
||||
- PREF
|
||||
- UKWN
|
||||
|
||||
Investor:
|
||||
type: object
|
||||
description: Анкета инвестора.
|
||||
required:
|
||||
- last_name
|
||||
- first_name
|
||||
- document
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: UUID инвестора в ЛК (если уже известен).
|
||||
last_name:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: Иванов
|
||||
first_name:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: Иван
|
||||
middle_name:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: Иванович
|
||||
document:
|
||||
$ref: '#/components/schemas/IdentityDocument'
|
||||
|
||||
IdentityDocument:
|
||||
type: object
|
||||
description: Документ, удостоверяющий личность.
|
||||
required:
|
||||
- document_type
|
||||
- number
|
||||
properties:
|
||||
document_type:
|
||||
type: string
|
||||
pattern: '^(0[1-7]|09|1[0-4]|2[1-37]|26|91)$'
|
||||
description: Код документа по справочнику НРД.
|
||||
example: '21'
|
||||
series:
|
||||
type: string
|
||||
pattern: '^\S+$'
|
||||
example: '4512'
|
||||
number:
|
||||
type: string
|
||||
pattern: '^\S+$'
|
||||
example: '654321'
|
||||
|
||||
Quantity:
|
||||
type: object
|
||||
description: Количество ценных бумаг — choice (ровно одно поле).
|
||||
properties:
|
||||
whole:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
example: 1500
|
||||
fractional:
|
||||
type: string
|
||||
description: Десятичная строка с не более 16 знаками после точки.
|
||||
pattern: '^[0-9]+(\.[0-9]{1,16})?$'
|
||||
example: '2500.75'
|
||||
|
||||
FundShares:
|
||||
type: object
|
||||
required:
|
||||
- reg_number
|
||||
properties:
|
||||
reg_number:
|
||||
type: string
|
||||
maxLength: 256
|
||||
example: '23-001'
|
||||
class:
|
||||
type: string
|
||||
maxLength: 120
|
||||
example: A
|
||||
|
||||
IdentificationDetails:
|
||||
type: object
|
||||
description: Идентификация ЦБ — choice (ровно одно поле).
|
||||
properties:
|
||||
reg_number:
|
||||
type: string
|
||||
maxLength: 20
|
||||
fund_shares:
|
||||
$ref: '#/components/schemas/FundShares'
|
||||
|
||||
SecurityInfo:
|
||||
type: object
|
||||
description: Описание ЦБ при отсутствии ISIN.
|
||||
required:
|
||||
- classification
|
||||
- category
|
||||
- identification_details
|
||||
properties:
|
||||
classification:
|
||||
$ref: '#/components/schemas/SecurityClassification'
|
||||
category:
|
||||
$ref: '#/components/schemas/SecurityCategory'
|
||||
security_type:
|
||||
type: string
|
||||
maxLength: 256
|
||||
security_series:
|
||||
type: string
|
||||
identification_details:
|
||||
$ref: '#/components/schemas/IdentificationDetails'
|
||||
|
||||
SecurityDetails:
|
||||
type: object
|
||||
description: Идентификация ЦБ — choice (ровно одно поле).
|
||||
properties:
|
||||
isin:
|
||||
type: string
|
||||
pattern: '^[A-Z]{2}[A-Z0-9]{9}[0-9]$'
|
||||
example: RU0007661625
|
||||
security_info:
|
||||
$ref: '#/components/schemas/SecurityInfo'
|
||||
|
||||
SettlementLocation:
|
||||
type: object
|
||||
required:
|
||||
- deponent_code
|
||||
- account_id
|
||||
- section_id
|
||||
properties:
|
||||
deponent_code:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: DP789456
|
||||
account_id:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: 31MC0021900000F01
|
||||
section_id:
|
||||
type: string
|
||||
maxLength: 50
|
||||
example: P001
|
||||
|
||||
SettlementAccount:
|
||||
type: object
|
||||
required:
|
||||
- settlement_requisites_inn
|
||||
- settlement_location
|
||||
properties:
|
||||
settlement_requisites_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
example: '7702070139'
|
||||
settlement_location:
|
||||
$ref: '#/components/schemas/SettlementLocation'
|
||||
|
||||
ClaimSecurity:
|
||||
type: object
|
||||
required:
|
||||
- security_code
|
||||
- security_details
|
||||
- quantity
|
||||
- settlement_accounts
|
||||
properties:
|
||||
security_code:
|
||||
type: string
|
||||
pattern: '^[0-9A-Z_/-]{12}$'
|
||||
example: MM0766162534
|
||||
security_details:
|
||||
$ref: '#/components/schemas/SecurityDetails'
|
||||
quantity:
|
||||
$ref: '#/components/schemas/Quantity'
|
||||
settlement_accounts:
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
$ref: '#/components/schemas/SettlementAccount'
|
||||
|
||||
CostInfo:
|
||||
type: object
|
||||
description: |
|
||||
Информация об учёте стоимости приобретения. Choice: либо
|
||||
`yes` (с кодом депонента-источника), либо `no` (учёт не ведётся).
|
||||
properties:
|
||||
yes:
|
||||
type: object
|
||||
required: [code]
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
pattern: '^[A-Z0-9]+$'
|
||||
maxLength: 12
|
||||
example: MC0010300032
|
||||
no:
|
||||
type: object
|
||||
description: Пустой объект — учёт не ведётся.
|
||||
|
||||
IIAAgreement:
|
||||
type: object
|
||||
description: Реквизиты договора ИИС (нужно, если перевод идёт по ИИС).
|
||||
required:
|
||||
- agreement_type
|
||||
- agreement_number
|
||||
- agreement_date
|
||||
- broker_inn
|
||||
properties:
|
||||
agreement_type:
|
||||
$ref: '#/components/schemas/AgreementType'
|
||||
agreement_number:
|
||||
type: string
|
||||
maxLength: 128
|
||||
example: ИИС78/2024
|
||||
agreement_date:
|
||||
type: string
|
||||
format: date
|
||||
example: '2026-01-15'
|
||||
broker_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
example: '0707083893'
|
||||
|
||||
CreateClaimRequest:
|
||||
type: object
|
||||
required:
|
||||
- investor
|
||||
- transferring_depository_inn
|
||||
- receiving_depository_inn
|
||||
- cost_info
|
||||
- securities
|
||||
- signed_document
|
||||
- signature_format
|
||||
properties:
|
||||
investor:
|
||||
$ref: '#/components/schemas/Investor'
|
||||
transferring_depository_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
receiving_depository_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
cost_info:
|
||||
$ref: '#/components/schemas/CostInfo'
|
||||
iia_agreement:
|
||||
$ref: '#/components/schemas/IIAAgreement'
|
||||
securities:
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
$ref: '#/components/schemas/ClaimSecurity'
|
||||
signed_document:
|
||||
type: string
|
||||
format: byte
|
||||
description: Подписанный XML заявления в base64.
|
||||
signature_format:
|
||||
$ref: '#/components/schemas/SignatureFormat'
|
||||
|
||||
CreateClaimResponse:
|
||||
type: object
|
||||
required: [id, status, created_at, success]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
status:
|
||||
$ref: '#/components/schemas/ClaimStatus'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
|
||||
Claim:
|
||||
type: object
|
||||
description: Полная сущность заявки.
|
||||
required:
|
||||
- id
|
||||
- status
|
||||
- created_at
|
||||
- updated_at
|
||||
- investor
|
||||
- transferring_depository_inn
|
||||
- receiving_depository_inn
|
||||
- securities
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
status:
|
||||
$ref: '#/components/schemas/ClaimStatus'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
investor:
|
||||
$ref: '#/components/schemas/Investor'
|
||||
transferring_depository_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
receiving_depository_inn:
|
||||
type: string
|
||||
pattern: '^[0-9]{10}$'
|
||||
cost_info:
|
||||
$ref: '#/components/schemas/CostInfo'
|
||||
iia_agreement:
|
||||
$ref: '#/components/schemas/IIAAgreement'
|
||||
securities:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ClaimSecurity'
|
||||
last_callback:
|
||||
$ref: '#/components/schemas/StatusCallback'
|
||||
|
||||
ClaimsPage:
|
||||
type: object
|
||||
required: [items, total, limit, offset]
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Claim'
|
||||
total:
|
||||
type: integer
|
||||
minimum: 0
|
||||
limit:
|
||||
type: integer
|
||||
offset:
|
||||
type: integer
|
||||
|
||||
StatusCallback:
|
||||
type: object
|
||||
description: Callback обновления статуса от lk-gateway к ЛК.
|
||||
required:
|
||||
- claim_id
|
||||
- new_status
|
||||
- updated_at
|
||||
properties:
|
||||
claim_id:
|
||||
type: string
|
||||
format: uuid
|
||||
new_status:
|
||||
$ref: '#/components/schemas/ClaimStatus'
|
||||
reason_code:
|
||||
type: string
|
||||
maxLength: 6
|
||||
description: Код причины (для rejected/timed_out) из M2MTransferResponse или M2MTransferDecision.
|
||||
example: '01'
|
||||
reason_text:
|
||||
type: string
|
||||
maxLength: 1024
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nsd_response:
|
||||
type: object
|
||||
description: Оригинал ответа НРД (необязательно, для аудита).
|
||||
properties:
|
||||
guid:
|
||||
type: string
|
||||
format: uuid
|
||||
status_code:
|
||||
type: string
|
||||
enum: [INFO, ERROR]
|
||||
responses:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
reference_id:
|
||||
type: string
|
||||
pattern: '^M2M[A-Z0-9]{13}$'
|
||||
code:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
|
||||
CallbackResponse:
|
||||
type: object
|
||||
required: [success]
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
description: Формат ошибки, идентичный API ESIA Finance V1.
|
||||
required: [error, status]
|
||||
properties:
|
||||
error:
|
||||
type: boolean
|
||||
example: true
|
||||
status:
|
||||
type: integer
|
||||
example: 422
|
||||
code:
|
||||
type: string
|
||||
example: invalid_signature
|
||||
title:
|
||||
type: string
|
||||
example: Подпись не прошла проверку
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
errors:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
Reference in New Issue
Block a user