From ad57a5679fa952d1d629c6d728549d82c22e48a8 Mon Sep 17 00:00:00 2001 From: alxeg Date: Fri, 3 Apr 2026 10:07:49 +0300 Subject: [PATCH] Add claude-generated openapi spec --- openapi.yaml | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 openapi.yaml diff --git a/openapi.yaml b/openapi.yaml new file mode 100644 index 0000000..db06f06 --- /dev/null +++ b/openapi.yaml @@ -0,0 +1,415 @@ +openapi: 3.1.0 +info: + title: Payouts Service API + description: API for managing user registrations, authentication, and payouts via YooKassa. + version: 1.0.0 + +servers: + - url: / + +tags: + - name: user + description: User registration and authentication + - name: payout + description: Payout operations + - name: system + description: Health and version endpoints + +paths: + /api/v1/user/register: + post: + tags: [user] + summary: Register a new user + operationId: userRegister + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserRegisterRequest' + responses: + '201': + description: User created successfully + '400': + description: Invalid input (empty fields or password mismatch) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /api/v1/user/login: + post: + tags: [user] + summary: Authenticate a user and obtain a session token + operationId: userLogin + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserLoginRequest' + responses: + '200': + description: Login successful + content: + application/json: + schema: + $ref: '#/components/schemas/UserLoginResponse' + '400': + description: Invalid input (empty phone or password) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Invalid credentials + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /api/v1/payout/sbp/banks: + get: + tags: [payout] + summary: Get list of SBP (Fast Payment System) banks + operationId: getSbpBanks + responses: + '200': + description: List of SBP banks + content: + application/json: + schema: + $ref: '#/components/schemas/SBPBankListResponse' + '400': + description: Bad request (YooKassa API error) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /api/v1/payout/create: + post: + tags: [payout] + summary: Create a new payout + operationId: createPayout + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutRequest' + responses: + '200': + description: Payout created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutResponse' + '400': + description: Invalid payout data + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized (missing or invalid token) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /api/v1/payout/callback: + post: + tags: [payout] + summary: Receive payout status callback from YooKassa + description: | + Called by YooKassa to notify of payout status changes. + If IP validation is enabled, the request must originate from an allowed subnet. + Status updates are processed asynchronously. + operationId: payoutCallback + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutResponse' + responses: + '200': + description: Callback received and queued for processing + '400': + description: Invalid JSON payload + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden (IP address not in allowed subnets) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /payout/widget: + get: + tags: [payout] + summary: Serve the payout widget HTML page + operationId: getPayoutWidget + responses: + '200': + description: Widget HTML page + content: + text/html: + schema: + type: string + '500': + description: Template rendering error + + /health: + get: + tags: [system] + summary: Health check + description: Verifies database connectivity. + operationId: healthCheck + responses: + '200': + description: Service is healthy + content: + application/json: + schema: + $ref: '#/components/schemas/HealthResponse' + '503': + description: Service unavailable (database connection failed) + content: + application/json: + schema: + $ref: '#/components/schemas/HealthResponse' + + /version: + get: + tags: [system] + summary: Get service version + operationId: getVersion + responses: + '200': + description: Version string (optionally including git commit hash) + content: + text/plain: + schema: + type: string + example: v1.2.3 + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + description: UUID session token obtained from the login endpoint + + schemas: + UserRegisterRequest: + type: object + required: [tin, phone, password, password_cfm] + properties: + tin: + type: string + description: Taxpayer Identification Number + example: "1234567890" + phone: + type: string + description: User phone number + example: "+79001234567" + password: + type: string + format: password + description: User password + password_cfm: + type: string + format: password + description: Password confirmation (must match password) + + UserLoginRequest: + type: object + required: [phone, password] + properties: + phone: + type: string + description: Registered phone number + example: "+79001234567" + password: + type: string + format: password + + UserLoginResponse: + type: object + properties: + token: + type: string + format: uuid + description: Session token (UUID) + example: "550e8400-e29b-41d4-a716-446655440000" + token_ttl: + type: integer + format: int64 + description: Token expiration as Unix timestamp + example: 1711958400 + + SBPBankListResponse: + type: object + properties: + type: + type: string + example: "list" + items: + type: array + items: + $ref: '#/components/schemas/SBPBank' + + SBPBank: + type: object + properties: + bank_id: + type: string + description: Bank identifier + example: "100000000111" + name: + type: string + description: Human-readable bank name + example: "Sberbank" + bic: + type: string + description: Bank Identification Code + example: "044525225" + + PayoutType: + type: string + enum: [spb, yoo_money, bank_card, widget] + description: | + Payout method: + - `spb` — Fast Payment System (SBP) + - `yoo_money` — YooMoney wallet + - `bank_card` — bank card + - `widget` — card via widget + + PayoutRequest: + type: object + required: [payout_type, amount] + properties: + payout_type: + $ref: '#/components/schemas/PayoutType' + payout_token: + type: string + description: Payment token (used for widget/card payouts) + example: "pt_xxxxxxxxxxxxxxxxxxxx" + account_number: + type: string + description: Account/phone number for SBP or YooMoney payouts + example: "+79001234567" + bank_id: + type: string + description: Bank identifier (required for SBP payouts) + example: "100000000111" + card_number: + type: string + description: Card number (for bank_card payout type) + example: "4111111111111111" + amount: + type: number + format: float + description: Payout amount in RUB + example: 1000.00 + + PayoutStatus: + type: string + enum: [created, pending, succeeded, canceled, failed] + + Amount: + type: object + properties: + value: + type: string + description: Amount as a decimal string + example: "1000.00" + currency: + type: string + description: ISO 4217 currency code + example: "RUB" + + PayoutDestination: + type: object + description: Payout destination details (structure depends on payout type) + additionalProperties: true + + PayoutResponse: + type: object + properties: + id: + type: string + description: YooKassa payout ID + example: "po_1da5c87d-0984-50e8-a7f3-8de646dd9ec9" + status: + $ref: '#/components/schemas/PayoutStatus' + amount: + $ref: '#/components/schemas/Amount' + payout_destination: + $ref: '#/components/schemas/PayoutDestination' + description: + type: string + example: "Payout for order #42" + created_at: + type: string + format: date-time + example: "2024-04-02T12:00:00Z" + succeeded_at: + type: string + format: date-time + example: "2024-04-02T12:01:00Z" + metadata: + type: object + additionalProperties: true + description: Arbitrary key-value metadata + test: + type: boolean + description: Whether this is a test payout + example: false + + HealthResponse: + type: object + properties: + OK: + type: boolean + description: Whether the service is healthy + Error: + type: string + description: Error message (only present when OK is false) + + ErrorResponse: + type: object + properties: + status: + type: integer + description: HTTP status code + example: 400 + message: + type: string + description: Human-readable error message + example: "Bad Request"