diff --git a/ci/dev/Caddyfile.dev b/ci/dev/Caddyfile.dev index b32d5780..50ebe0c0 100644 --- a/ci/dev/Caddyfile.dev +++ b/ci/dev/Caddyfile.dev @@ -37,6 +37,26 @@ header Cache-Control "no-cache, no-store, must-revalidate" } + ######################################## + # API docs (ReDoc) + ######################################## + handle /docs { + redir * /docs/ 308 + } + + handle /docs/ { + root * {vars.static_root}/docs + rewrite * /doc.html + file_server + header Cache-Control "no-cache" + } + + handle_path /docs/* { + root * {vars.static_root}/docs + file_server + header Cache-Control "no-cache" + } + ######################################## # Static assets ######################################## diff --git a/ci/dev/frontend.dockerfile b/ci/dev/frontend.dockerfile index 21d61007..799c8f34 100644 --- a/ci/dev/frontend.dockerfile +++ b/ci/dev/frontend.dockerfile @@ -48,6 +48,7 @@ FROM caddy:alpine AS runtime WORKDIR /usr/share/pweb COPY --from=web_builder /home/flutteruser/app/pweb/build/web /usr/share/pweb +COPY interface /usr/share/pweb/docs # Copy Caddy config (will be mounted from host) # COPY frontend/pweb/caddy/Caddyfile /etc/caddy/Caddyfile diff --git a/ci/prod/compose/frontend.dockerfile b/ci/prod/compose/frontend.dockerfile index d48315b8..91ebe084 100644 --- a/ci/prod/compose/frontend.dockerfile +++ b/ci/prod/compose/frontend.dockerfile @@ -45,6 +45,7 @@ WORKDIR /usr/share/pweb COPY frontend/pweb/entrypoint.sh /entrypoint.sh COPY frontend/pweb/caddy/Caddyfile /etc/caddy/Caddyfile COPY --from=web_builder /home/flutteruser/app/pweb/build/web /usr/share/pweb +COPY interface /usr/share/pweb/docs RUN chmod +x /entrypoint.sh diff --git a/interface/api.yaml b/interface/api.yaml new file mode 100644 index 00000000..72dc6254 --- /dev/null +++ b/interface/api.yaml @@ -0,0 +1,89 @@ +openapi: 3.1.0 +info: + title: Sendico Payment API Contract + version: 1.0.0 + summary: Minimal client contract for payment execution flows via BFF. + description: | + OpenAPI 3.1 contract focused on flows required to perform payments: + authentication, verification, recipients, payment methods and payments. +servers: + - url: /api/v1 + description: Main HTTP API base path + +tags: + - name: Auth + description: Authentication and token lifecycle + - name: Accounts + description: Account auth responses used by login/verification + - name: Verification + description: Pending-account code verification + - name: Organizations + description: Organization selection for payment operations + - name: Recipients + description: Recipient CRUD and archive flows + - name: PaymentMethods + description: Payment method CRUD and archive flows + - name: Payments + description: Quotation and payment orchestration + +paths: + /accounts/login: + $ref: ./api/accounts/auth_login.yaml + /accounts/rotate: + $ref: ./api/accounts/auth_rotate.yaml + /accounts/refresh: + $ref: ./api/accounts/auth_refresh.yaml + + /verification: + $ref: ./api/verification/create.yaml + /verification/resend: + $ref: ./api/verification/resend.yaml + /verification/verify: + $ref: ./api/verification/verify.yaml + + /organizations: + $ref: ./api/organizations/root.yaml + /organizations/{org_ref}: + $ref: ./api/organizations/get.yaml + + /recipients/list/{org_ref}/{organizations_ref}: + $ref: ./api/recipients/list.yaml + /recipients/{org_ref}: + $ref: ./api/recipients/create.yaml + /recipients/{recipients_ref}: + $ref: ./api/recipients/object.yaml + /recipients: + $ref: ./api/recipients/update.yaml + /recipients/archive/{org_ref}/{recipients_ref}: + $ref: ./api/recipients/archive.yaml + + /payment_methods/list/{organizations_ref}/{recipients_ref}: + $ref: ./api/payment_methods/list.yaml + /payment_methods/{organizations_ref}: + $ref: ./api/payment_methods/create.yaml + /payment_methods/{payment_methods_ref}: + $ref: ./api/payment_methods/object.yaml + /payment_methods: + $ref: ./api/payment_methods/update.yaml + /payment_methods/archive/{organizations_ref}/{payment_methods_ref}: + $ref: ./api/payment_methods/archive.yaml + + /payments/quote/{organizations_ref}: + $ref: ./api/payments/quote.yaml + /payments/multiquote/{organizations_ref}: + $ref: ./api/payments/multiquote.yaml + /payments/immediate/{organizations_ref}: + $ref: ./api/payments/immediate.yaml + /payments/by-quote/{organizations_ref}: + $ref: ./api/payments/by_quote.yaml + /payments/by-multiquote/{organizations_ref}: + $ref: ./api/payments/by_multiquote.yaml + /payments/{organizations_ref}: + $ref: ./api/payments/list.yaml + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT diff --git a/interface/api/accounts/auth_login.yaml b/interface/api/accounts/auth_login.yaml new file mode 100644 index 00000000..34a49f97 --- /dev/null +++ b/interface/api/accounts/auth_login.yaml @@ -0,0 +1,26 @@ +post: + tags: [Accounts, Auth] + summary: Login using email/password and receive pending verification token + operationId: accountsLogin + requestBody: + $ref: ./bodies/auth.yaml#/components/requestBodies/LoginBody + responses: + '202': + description: Pending verification token issued + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/auth.yaml#/components/schemas/PendingLoginData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/accounts/auth_refresh.yaml b/interface/api/accounts/auth_refresh.yaml new file mode 100644 index 00000000..7f573d17 --- /dev/null +++ b/interface/api/accounts/auth_refresh.yaml @@ -0,0 +1,28 @@ +post: + tags: [Accounts, Auth] + summary: Refresh access token by refresh token + operationId: accountsRefreshAccessToken + requestBody: + $ref: ./bodies/auth.yaml#/components/requestBodies/RefreshTokenBody + responses: + '200': + description: Access token refreshed + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/auth.yaml#/components/schemas/AccountAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/accounts/auth_rotate.yaml b/interface/api/accounts/auth_rotate.yaml new file mode 100644 index 00000000..2cb6debc --- /dev/null +++ b/interface/api/accounts/auth_rotate.yaml @@ -0,0 +1,28 @@ +post: + tags: [Accounts, Auth] + summary: Rotate refresh token and issue new access/refresh tokens + operationId: accountsRotateRefreshToken + requestBody: + $ref: ./bodies/auth.yaml#/components/requestBodies/RefreshTokenBody + responses: + '200': + description: New token pair issued + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/auth.yaml#/components/schemas/LoginData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/accounts/bodies/auth.yaml b/interface/api/accounts/bodies/auth.yaml new file mode 100644 index 00000000..44b94437 --- /dev/null +++ b/interface/api/accounts/bodies/auth.yaml @@ -0,0 +1,15 @@ +components: + requestBodies: + LoginBody: + required: true + content: + application/json: + schema: + $ref: ../request/auth.yaml#/components/schemas/LoginRequest + + RefreshTokenBody: + required: true + content: + application/json: + schema: + $ref: ../request/auth.yaml#/components/schemas/RefreshTokenRequest diff --git a/interface/api/accounts/request/auth.yaml b/interface/api/accounts/request/auth.yaml new file mode 100644 index 00000000..09c50395 --- /dev/null +++ b/interface/api/accounts/request/auth.yaml @@ -0,0 +1,17 @@ +components: + schemas: + LoginRequest: + type: object + additionalProperties: false + required: + - login + properties: + clientId: + type: string + deviceId: + type: string + login: + $ref: ../../../models/auth/login_data.yaml#/components/schemas/LoginData + + RefreshTokenRequest: + $ref: ../../../models/auth/client_refresh_token.yaml#/components/schemas/ClientRefreshToken diff --git a/interface/api/accounts/response/auth.yaml b/interface/api/accounts/response/auth.yaml new file mode 100644 index 00000000..9649a73e --- /dev/null +++ b/interface/api/accounts/response/auth.yaml @@ -0,0 +1,49 @@ +components: + schemas: + AccountAuthData: + type: object + additionalProperties: false + required: + - accessToken + - account + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + account: + $ref: ../../../models/account/account.yaml#/components/schemas/AccountData + + LoginData: + type: object + additionalProperties: false + required: + - accessToken + - account + - refreshToken + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + account: + $ref: ../../../models/account/account.yaml#/components/schemas/AccountData + refreshToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + + PendingLoginData: + type: object + additionalProperties: false + required: + - account + - pendingToken + - target + properties: + account: + type: object + additionalProperties: false + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + account: + $ref: ../../../models/account/account.yaml#/components/schemas/AccountData + pendingToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + target: + type: string diff --git a/interface/api/organizations/get.yaml b/interface/api/organizations/get.yaml new file mode 100644 index 00000000..02f57615 --- /dev/null +++ b/interface/api/organizations/get.yaml @@ -0,0 +1,28 @@ +get: + tags: [Organizations] + summary: Get organization by reference + operationId: organizationsGet + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef + responses: + '200': + description: Organization details + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/organization.yaml#/components/schemas/OrganizationsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/organizations/response/organization.yaml b/interface/api/organizations/response/organization.yaml new file mode 100644 index 00000000..5ef7b813 --- /dev/null +++ b/interface/api/organizations/response/organization.yaml @@ -0,0 +1,15 @@ +components: + schemas: + OrganizationsAuthData: + type: object + additionalProperties: false + required: + - accessToken + - organizations + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + organizations: + type: array + items: + $ref: ../../../models/organization/organization.yaml#/components/schemas/Organization diff --git a/interface/api/organizations/root.yaml b/interface/api/organizations/root.yaml new file mode 100644 index 00000000..4329ae4d --- /dev/null +++ b/interface/api/organizations/root.yaml @@ -0,0 +1,26 @@ +get: + tags: [Organizations] + summary: List organizations of current account + operationId: organizationsList + security: + - bearerAuth: [] + responses: + '200': + description: Organizations list + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/organization.yaml#/components/schemas/OrganizationsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/parameters/archived.yaml b/interface/api/parameters/archived.yaml new file mode 100644 index 00000000..02c370ef --- /dev/null +++ b/interface/api/parameters/archived.yaml @@ -0,0 +1,8 @@ +components: + parameters: + Archived: + name: archived + in: query + required: false + schema: + type: boolean diff --git a/interface/api/parameters/cascade.yaml b/interface/api/parameters/cascade.yaml new file mode 100644 index 00000000..bdaf7858 --- /dev/null +++ b/interface/api/parameters/cascade.yaml @@ -0,0 +1,8 @@ +components: + parameters: + Cascade: + name: cascade + in: query + required: false + schema: + type: boolean diff --git a/interface/api/parameters/cursor.yaml b/interface/api/parameters/cursor.yaml new file mode 100644 index 00000000..f4f0f7b8 --- /dev/null +++ b/interface/api/parameters/cursor.yaml @@ -0,0 +1,8 @@ +components: + parameters: + Cursor: + name: cursor + in: query + required: false + schema: + type: string diff --git a/interface/api/parameters/destination_ref.yaml b/interface/api/parameters/destination_ref.yaml new file mode 100644 index 00000000..3d8cc267 --- /dev/null +++ b/interface/api/parameters/destination_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + DestinationRef: + name: destination_ref + in: query + required: false + schema: + type: string diff --git a/interface/api/parameters/filter_states.yaml b/interface/api/parameters/filter_states.yaml new file mode 100644 index 00000000..821b60cb --- /dev/null +++ b/interface/api/parameters/filter_states.yaml @@ -0,0 +1,8 @@ +components: + parameters: + FilterStates: + name: filter_states + in: query + required: false + schema: + type: string diff --git a/interface/api/parameters/limit.yaml b/interface/api/parameters/limit.yaml new file mode 100644 index 00000000..fe30c130 --- /dev/null +++ b/interface/api/parameters/limit.yaml @@ -0,0 +1,11 @@ +components: + parameters: + Limit: + name: limit + in: query + description: Max number of items to return. + required: false + schema: + type: integer + format: int32 + minimum: 0 diff --git a/interface/api/parameters/offset.yaml b/interface/api/parameters/offset.yaml new file mode 100644 index 00000000..f9d1bc60 --- /dev/null +++ b/interface/api/parameters/offset.yaml @@ -0,0 +1,11 @@ +components: + parameters: + Offset: + name: offset + in: query + description: Number of items to skip. + required: false + schema: + type: integer + format: int32 + minimum: 0 diff --git a/interface/api/parameters/org_ref.yaml b/interface/api/parameters/org_ref.yaml new file mode 100644 index 00000000..de524623 --- /dev/null +++ b/interface/api/parameters/org_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + OrgRef: + name: org_ref + in: path + required: true + schema: + $ref: ../../models/objectid.yaml#/components/schemas/ObjectId diff --git a/interface/api/parameters/organizations_ref.yaml b/interface/api/parameters/organizations_ref.yaml new file mode 100644 index 00000000..7f2c7e6c --- /dev/null +++ b/interface/api/parameters/organizations_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + OrganizationsRef: + name: organizations_ref + in: path + required: true + schema: + $ref: ../../models/objectid.yaml#/components/schemas/ObjectId diff --git a/interface/api/parameters/payment_methods_ref.yaml b/interface/api/parameters/payment_methods_ref.yaml new file mode 100644 index 00000000..f8707b45 --- /dev/null +++ b/interface/api/parameters/payment_methods_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + PaymentMethodsRef: + name: payment_methods_ref + in: path + required: true + schema: + $ref: ../../models/objectid.yaml#/components/schemas/ObjectId diff --git a/interface/api/parameters/recipients_ref.yaml b/interface/api/parameters/recipients_ref.yaml new file mode 100644 index 00000000..8808f21e --- /dev/null +++ b/interface/api/parameters/recipients_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + RecipientsRef: + name: recipients_ref + in: path + required: true + schema: + $ref: ../../models/objectid.yaml#/components/schemas/ObjectId diff --git a/interface/api/parameters/source_ref.yaml b/interface/api/parameters/source_ref.yaml new file mode 100644 index 00000000..a7f01187 --- /dev/null +++ b/interface/api/parameters/source_ref.yaml @@ -0,0 +1,8 @@ +components: + parameters: + SourceRef: + name: source_ref + in: query + required: false + schema: + type: string diff --git a/interface/api/parameters/state.yaml b/interface/api/parameters/state.yaml new file mode 100644 index 00000000..36e604fe --- /dev/null +++ b/interface/api/parameters/state.yaml @@ -0,0 +1,8 @@ +components: + parameters: + State: + name: state + in: query + required: false + schema: + type: string diff --git a/interface/api/parameters/states.yaml b/interface/api/parameters/states.yaml new file mode 100644 index 00000000..b85cfd82 --- /dev/null +++ b/interface/api/parameters/states.yaml @@ -0,0 +1,8 @@ +components: + parameters: + States: + name: states + in: query + required: false + schema: + type: string diff --git a/interface/api/payment_methods/archive.yaml b/interface/api/payment_methods/archive.yaml new file mode 100644 index 00000000..31a48580 --- /dev/null +++ b/interface/api/payment_methods/archive.yaml @@ -0,0 +1,35 @@ +get: + tags: [PaymentMethods] + summary: Archive/unarchive payment method + operationId: paymentMethodsArchive + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + - $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/PaymentMethodsRef + - name: archived + in: query + required: true + schema: + type: boolean + - $ref: ../parameters/cascade.yaml#/components/parameters/Cascade + responses: + '200': + description: Archive state updated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payment_methods/bodies/payment_method.yaml b/interface/api/payment_methods/bodies/payment_method.yaml new file mode 100644 index 00000000..090086de --- /dev/null +++ b/interface/api/payment_methods/bodies/payment_method.yaml @@ -0,0 +1,8 @@ +components: + requestBodies: + PaymentMethodBody: + required: true + content: + application/json: + schema: + $ref: ../request/payment_method.yaml#/components/schemas/PaymentMethodRequest diff --git a/interface/api/payment_methods/create.yaml b/interface/api/payment_methods/create.yaml new file mode 100644 index 00000000..f64dd384 --- /dev/null +++ b/interface/api/payment_methods/create.yaml @@ -0,0 +1,34 @@ +post: + tags: [PaymentMethods] + summary: Create payment method + operationId: paymentMethodsCreate + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + $ref: ./bodies/payment_method.yaml#/components/requestBodies/PaymentMethodBody + responses: + '201': + description: Payment method created + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payment_methods/list.yaml b/interface/api/payment_methods/list.yaml new file mode 100644 index 00000000..3f0e2ece --- /dev/null +++ b/interface/api/payment_methods/list.yaml @@ -0,0 +1,34 @@ +get: + tags: [PaymentMethods] + summary: List payment methods for recipient + operationId: paymentMethodsList + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + - $ref: ../parameters/recipients_ref.yaml#/components/parameters/RecipientsRef + - $ref: ../parameters/limit.yaml#/components/parameters/Limit + - $ref: ../parameters/offset.yaml#/components/parameters/Offset + - $ref: ../parameters/archived.yaml#/components/parameters/Archived + responses: + '200': + description: Payment methods list + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payment_methods/object.yaml b/interface/api/payment_methods/object.yaml new file mode 100644 index 00000000..6ae62feb --- /dev/null +++ b/interface/api/payment_methods/object.yaml @@ -0,0 +1,62 @@ +get: + tags: [PaymentMethods] + summary: Get payment method + operationId: paymentMethodsGet + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/PaymentMethodsRef + responses: + '200': + description: Payment method data + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError + +delete: + tags: [PaymentMethods] + summary: Delete payment method + operationId: paymentMethodsDelete + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/PaymentMethodsRef + - $ref: ../parameters/cascade.yaml#/components/parameters/Cascade + responses: + '200': + description: Payment method deleted + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payment_methods/request/payment_method.yaml b/interface/api/payment_methods/request/payment_method.yaml new file mode 100644 index 00000000..ed55b7f6 --- /dev/null +++ b/interface/api/payment_methods/request/payment_method.yaml @@ -0,0 +1,4 @@ +components: + schemas: + PaymentMethodRequest: + $ref: ../../../models/payment_method/payment_method.yaml#/components/schemas/PaymentMethod diff --git a/interface/api/payment_methods/response/payment_method.yaml b/interface/api/payment_methods/response/payment_method.yaml new file mode 100644 index 00000000..2389bcd4 --- /dev/null +++ b/interface/api/payment_methods/response/payment_method.yaml @@ -0,0 +1,15 @@ +components: + schemas: + PaymentMethodsAuthData: + type: object + additionalProperties: false + required: + - accessToken + - payment_methods + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + payment_methods: + type: array + items: + $ref: ../../../models/payment_method/payment_method.yaml#/components/schemas/PaymentMethod diff --git a/interface/api/payment_methods/update.yaml b/interface/api/payment_methods/update.yaml new file mode 100644 index 00000000..d7e0d70b --- /dev/null +++ b/interface/api/payment_methods/update.yaml @@ -0,0 +1,32 @@ +put: + tags: [PaymentMethods] + summary: Update payment method + operationId: paymentMethodsUpdate + security: + - bearerAuth: [] + requestBody: + $ref: ./bodies/payment_method.yaml#/components/requestBodies/PaymentMethodBody + responses: + '200': + description: Payment method updated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment_method.yaml#/components/schemas/PaymentMethodsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/bodies/payment.yaml b/interface/api/payments/bodies/payment.yaml new file mode 100644 index 00000000..bd772ddb --- /dev/null +++ b/interface/api/payments/bodies/payment.yaml @@ -0,0 +1,29 @@ +components: + requestBodies: + QuotePaymentBody: + required: true + content: + application/json: + schema: + $ref: ../request/payment.yaml#/components/schemas/QuotePaymentRequest + + QuotePaymentsBody: + required: true + content: + application/json: + schema: + $ref: ../request/payment.yaml#/components/schemas/QuotePaymentsRequest + + InitiatePaymentBody: + required: true + content: + application/json: + schema: + $ref: ../request/payment.yaml#/components/schemas/InitiatePaymentRequest + + InitiatePaymentsBody: + required: true + content: + application/json: + schema: + $ref: ../request/payment.yaml#/components/schemas/InitiatePaymentsRequest diff --git a/interface/api/payments/by_multiquote.yaml b/interface/api/payments/by_multiquote.yaml new file mode 100644 index 00000000..40e43035 --- /dev/null +++ b/interface/api/payments/by_multiquote.yaml @@ -0,0 +1,30 @@ +post: + tags: [Payments] + summary: Initiate payment batch by quote reference + operationId: paymentsInitiateBatchByQuote + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + $ref: ./bodies/payment.yaml#/components/requestBodies/InitiatePaymentsBody + responses: + '200': + description: Payment batch initiated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentsData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/by_quote.yaml b/interface/api/payments/by_quote.yaml new file mode 100644 index 00000000..7f6adc27 --- /dev/null +++ b/interface/api/payments/by_quote.yaml @@ -0,0 +1,41 @@ +post: + tags: [Payments] + summary: Initiate payment using quote reference + operationId: paymentsInitiateByQuote + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + required: true + content: + application/json: + schema: + allOf: + - $ref: ./request/payment.yaml#/components/schemas/InitiatePaymentRequest + - type: object + required: + - quoteRef + not: + required: + - intent + responses: + '200': + description: Payment initiated by quote + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/immediate.yaml b/interface/api/payments/immediate.yaml new file mode 100644 index 00000000..6952d188 --- /dev/null +++ b/interface/api/payments/immediate.yaml @@ -0,0 +1,41 @@ +post: + tags: [Payments] + summary: Initiate payment from immediate intent + operationId: paymentsInitiateImmediate + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + required: true + content: + application/json: + schema: + allOf: + - $ref: ./request/payment.yaml#/components/schemas/InitiatePaymentRequest + - type: object + required: + - intent + not: + required: + - quoteRef + responses: + '200': + description: Payment initiated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/list.yaml b/interface/api/payments/list.yaml new file mode 100644 index 00000000..5e30aa31 --- /dev/null +++ b/interface/api/payments/list.yaml @@ -0,0 +1,50 @@ +get: + tags: [Payments] + summary: List payments in organization + operationId: paymentsList + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + - $ref: ../parameters/cursor.yaml#/components/parameters/Cursor + - $ref: ../parameters/limit.yaml#/components/parameters/Limit + - name: quotation_ref + in: query + required: false + schema: + type: string + - name: created_from + in: query + required: false + schema: + type: string + format: date-time + - name: created_to + in: query + required: false + schema: + type: string + format: date-time + - $ref: ../parameters/state.yaml#/components/parameters/State + - $ref: ../parameters/states.yaml#/components/parameters/States + - $ref: ../parameters/filter_states.yaml#/components/parameters/FilterStates + responses: + '200': + description: Payments list + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentsData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/multiquote.yaml b/interface/api/payments/multiquote.yaml new file mode 100644 index 00000000..cfb7588a --- /dev/null +++ b/interface/api/payments/multiquote.yaml @@ -0,0 +1,30 @@ +post: + tags: [Payments] + summary: Quote multiple payment intents + operationId: paymentsMultiQuote + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + $ref: ./bodies/payment.yaml#/components/requestBodies/QuotePaymentsBody + responses: + '200': + description: Quotes generated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentQuotesData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/quote.yaml b/interface/api/payments/quote.yaml new file mode 100644 index 00000000..8fb5faaa --- /dev/null +++ b/interface/api/payments/quote.yaml @@ -0,0 +1,30 @@ +post: + tags: [Payments] + summary: Quote single payment intent + operationId: paymentsQuote + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + requestBody: + $ref: ./bodies/payment.yaml#/components/requestBodies/QuotePaymentBody + responses: + '200': + description: Quote generated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/payment.yaml#/components/schemas/PaymentQuoteData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/payments/request/payment.yaml b/interface/api/payments/request/payment.yaml new file mode 100644 index 00000000..1d4a9807 --- /dev/null +++ b/interface/api/payments/request/payment.yaml @@ -0,0 +1,104 @@ +components: + schemas: + PaymentBase: + type: object + additionalProperties: false + required: + - idempotencyKey + properties: + idempotencyKey: + type: string + metadata: + type: object + additionalProperties: + type: string + + QuotePaymentRequest: + type: object + additionalProperties: false + required: + - intent + properties: + idempotencyKey: + type: string + metadata: + type: object + additionalProperties: + type: string + intent: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent + previewOnly: + type: boolean + allOf: + - if: + properties: + previewOnly: + const: true + required: + - previewOnly + then: + not: + required: + - idempotencyKey + else: + required: + - idempotencyKey + + QuotePaymentsRequest: + type: object + additionalProperties: false + required: + - intents + properties: + idempotencyKey: + type: string + metadata: + type: object + additionalProperties: + type: string + intents: + type: array + minItems: 1 + items: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent + previewOnly: + type: boolean + allOf: + - if: + properties: + previewOnly: + const: true + required: + - previewOnly + then: + not: + required: + - idempotencyKey + else: + required: + - idempotencyKey + + InitiatePaymentRequest: + allOf: + - $ref: ./payment.yaml#/components/schemas/PaymentBase + - type: object + additionalProperties: false + oneOf: + - required: [intent] + - required: [quoteRef] + properties: + intent: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent + quoteRef: + type: string + + InitiatePaymentsRequest: + allOf: + - $ref: ./payment.yaml#/components/schemas/PaymentBase + - type: object + additionalProperties: false + required: + - quoteRef + properties: + quoteRef: + type: string diff --git a/interface/api/payments/response/payment.yaml b/interface/api/payments/response/payment.yaml new file mode 100644 index 00000000..b07fd49c --- /dev/null +++ b/interface/api/payments/response/payment.yaml @@ -0,0 +1,66 @@ +components: + schemas: + PaymentQuoteData: + type: object + additionalProperties: false + required: + - accessToken + - quote + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + idempotencyKey: + type: string + quote: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentQuote + + PaymentQuotesData: + type: object + additionalProperties: false + required: + - accessToken + - quote + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + quote: + type: object + additionalProperties: false + properties: + idempotencyKey: + type: string + quoteRef: + type: string + aggregate: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentQuoteAggregate + quotes: + type: array + items: + $ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentQuote + + PaymentsData: + type: object + additionalProperties: false + required: + - accessToken + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + payments: + type: array + items: + $ref: ../../../models/payment/payment.yaml#/components/schemas/Payment + page: + $ref: ../../../models/common/pagination.yaml#/components/schemas/CursorPageResponse + + PaymentData: + type: object + additionalProperties: false + required: + - accessToken + - payment + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + payment: + $ref: ../../../models/payment/payment.yaml#/components/schemas/Payment diff --git a/interface/api/recipients/archive.yaml b/interface/api/recipients/archive.yaml new file mode 100644 index 00000000..e1a29044 --- /dev/null +++ b/interface/api/recipients/archive.yaml @@ -0,0 +1,35 @@ +get: + tags: [Recipients] + summary: Archive/unarchive recipient + operationId: recipientsArchive + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef + - $ref: ../parameters/recipients_ref.yaml#/components/parameters/RecipientsRef + - name: archived + in: query + required: true + schema: + type: boolean + - $ref: ../parameters/cascade.yaml#/components/parameters/Cascade + responses: + '200': + description: Archive state updated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/recipients/bodies/recipient.yaml b/interface/api/recipients/bodies/recipient.yaml new file mode 100644 index 00000000..c4c6e152 --- /dev/null +++ b/interface/api/recipients/bodies/recipient.yaml @@ -0,0 +1,8 @@ +components: + requestBodies: + RecipientBody: + required: true + content: + application/json: + schema: + $ref: ../request/recipient.yaml#/components/schemas/RecipientRequest diff --git a/interface/api/recipients/create.yaml b/interface/api/recipients/create.yaml new file mode 100644 index 00000000..a68ab83b --- /dev/null +++ b/interface/api/recipients/create.yaml @@ -0,0 +1,32 @@ +post: + tags: [Recipients] + summary: Create recipient + operationId: recipientsCreate + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef + requestBody: + $ref: ./bodies/recipient.yaml#/components/requestBodies/RecipientBody + responses: + '201': + description: Recipient created + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/recipients/list.yaml b/interface/api/recipients/list.yaml new file mode 100644 index 00000000..d9b4aacb --- /dev/null +++ b/interface/api/recipients/list.yaml @@ -0,0 +1,32 @@ +get: + tags: [Recipients] + summary: List recipients + operationId: recipientsList + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef + - $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef + - $ref: ../parameters/limit.yaml#/components/parameters/Limit + - $ref: ../parameters/offset.yaml#/components/parameters/Offset + - $ref: ../parameters/archived.yaml#/components/parameters/Archived + responses: + '200': + description: Recipient list + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/recipients/object.yaml b/interface/api/recipients/object.yaml new file mode 100644 index 00000000..329f642c --- /dev/null +++ b/interface/api/recipients/object.yaml @@ -0,0 +1,62 @@ +get: + tags: [Recipients] + summary: Get recipient by reference + operationId: recipientsGet + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/recipients_ref.yaml#/components/parameters/RecipientsRef + responses: + '200': + description: Recipient data + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError + +delete: + tags: [Recipients] + summary: Delete recipient + operationId: recipientsDelete + security: + - bearerAuth: [] + parameters: + - $ref: ../parameters/recipients_ref.yaml#/components/parameters/RecipientsRef + - $ref: ../parameters/cascade.yaml#/components/parameters/Cascade + responses: + '200': + description: Recipient deleted + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/recipients/request/recipient.yaml b/interface/api/recipients/request/recipient.yaml new file mode 100644 index 00000000..7a96a78b --- /dev/null +++ b/interface/api/recipients/request/recipient.yaml @@ -0,0 +1,4 @@ +components: + schemas: + RecipientRequest: + $ref: ../../../models/recipient/recipient.yaml#/components/schemas/Recipient diff --git a/interface/api/recipients/response/recipient.yaml b/interface/api/recipients/response/recipient.yaml new file mode 100644 index 00000000..7b32cee2 --- /dev/null +++ b/interface/api/recipients/response/recipient.yaml @@ -0,0 +1,15 @@ +components: + schemas: + RecipientsAuthData: + type: object + additionalProperties: false + required: + - accessToken + - recipients + properties: + accessToken: + $ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData + recipients: + type: array + items: + $ref: ../../../models/recipient/recipient.yaml#/components/schemas/Recipient diff --git a/interface/api/recipients/update.yaml b/interface/api/recipients/update.yaml new file mode 100644 index 00000000..7b877e20 --- /dev/null +++ b/interface/api/recipients/update.yaml @@ -0,0 +1,30 @@ +put: + tags: [Recipients] + summary: Update recipient + operationId: recipientsUpdate + security: + - bearerAuth: [] + requestBody: + $ref: ./bodies/recipient.yaml#/components/requestBodies/RecipientBody + responses: + '200': + description: Recipient updated + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/recipient.yaml#/components/schemas/RecipientsAuthData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/response/error.yaml b/interface/api/response/error.yaml new file mode 100644 index 00000000..7801100e --- /dev/null +++ b/interface/api/response/error.yaml @@ -0,0 +1,19 @@ +components: + schemas: + ApiError: + type: object + additionalProperties: false + required: + - code + - error + - source + properties: + code: + type: integer + format: int32 + error: + type: string + source: + type: string + details: + type: string diff --git a/interface/api/response/operation.yaml b/interface/api/response/operation.yaml new file mode 100644 index 00000000..f6cf6c58 --- /dev/null +++ b/interface/api/response/operation.yaml @@ -0,0 +1,78 @@ +components: + responses: + Ok: + description: Successful response + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/BaseResponse + + Created: + description: Resource created + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/BaseResponse + + Accepted: + description: Request accepted for processing + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/BaseResponse + + BadRequest: + description: Bad request payload or query/path parameter + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + Unauthorized: + description: Unauthorized + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + Forbidden: + description: Forbidden + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + NotFound: + description: Resource not found + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + Gone: + description: Resource is no longer available + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + Conflict: + description: Conflict + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + TooManyRequests: + description: Too many requests + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse + + InternalServerError: + description: Internal server error + content: + application/json: + schema: + $ref: ./response.yaml#/components/schemas/ErrorResponse diff --git a/interface/api/response/response.yaml b/interface/api/response/response.yaml new file mode 100644 index 00000000..89589e58 --- /dev/null +++ b/interface/api/response/response.yaml @@ -0,0 +1,47 @@ +components: + schemas: + BaseResponse: + type: object + additionalProperties: false + required: + - status + - data + properties: + status: + $ref: ./status.yaml#/components/schemas/ApiStatus + data: + description: Payload for success or error responses. + + ErrorResponse: + allOf: + - $ref: ./response.yaml#/components/schemas/BaseResponse + - type: object + properties: + status: + type: string + enum: + - error + data: + $ref: ./error.yaml#/components/schemas/ApiError + + SuccessResultData: + type: object + additionalProperties: false + required: + - result + properties: + result: + type: boolean + + SuccessResultResponse: + allOf: + - $ref: ./response.yaml#/components/schemas/BaseResponse + - type: object + properties: + status: + type: string + enum: + - success + - processed + data: + $ref: ./response.yaml#/components/schemas/SuccessResultData diff --git a/interface/api/response/status.yaml b/interface/api/response/status.yaml new file mode 100644 index 00000000..1a7e1236 --- /dev/null +++ b/interface/api/response/status.yaml @@ -0,0 +1,10 @@ +components: + schemas: + ApiStatus: + type: string + description: Unified response status used by backend wrappers. + enum: + - success + - processed + - error + - request diff --git a/interface/api/verification/bodies/verification.yaml b/interface/api/verification/bodies/verification.yaml new file mode 100644 index 00000000..79cc79f9 --- /dev/null +++ b/interface/api/verification/bodies/verification.yaml @@ -0,0 +1,15 @@ +components: + requestBodies: + VerificationCodeBody: + required: true + content: + application/json: + schema: + $ref: ../request/verification.yaml#/components/schemas/VerificationCodeRequest + + VerifyCodeBody: + required: true + content: + application/json: + schema: + $ref: ../request/verification.yaml#/components/schemas/CodeVerificationRequest diff --git a/interface/api/verification/create.yaml b/interface/api/verification/create.yaml new file mode 100644 index 00000000..ad7bda97 --- /dev/null +++ b/interface/api/verification/create.yaml @@ -0,0 +1,34 @@ +post: + tags: [Verification, Auth] + summary: Request verification code + operationId: verificationRequestCode + security: + - bearerAuth: [] + requestBody: + $ref: ./bodies/verification.yaml#/components/requestBodies/VerificationCodeBody + responses: + '202': + description: Verification code requested + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/verification.yaml#/components/schemas/VerificationResponseData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '429': + $ref: ../response/operation.yaml#/components/responses/TooManyRequests + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/verification/request/verification.yaml b/interface/api/verification/request/verification.yaml new file mode 100644 index 00000000..52cd1e94 --- /dev/null +++ b/interface/api/verification/request/verification.yaml @@ -0,0 +1,31 @@ +components: + schemas: + VerificationCodeRequest: + type: object + additionalProperties: false + required: + - purpose + - idempotencyKey + properties: + purpose: + type: string + description: Verification purpose, e.g. login. + target: + type: string + format: email + idempotencyKey: + type: string + + CodeVerificationRequest: + allOf: + - $ref: ./verification.yaml#/components/schemas/VerificationCodeRequest + - type: object + additionalProperties: false + required: + - code + - sessionIdentifier + properties: + code: + type: string + sessionIdentifier: + $ref: ../../../models/auth/session_identifier.yaml#/components/schemas/SessionIdentifier diff --git a/interface/api/verification/resend.yaml b/interface/api/verification/resend.yaml new file mode 100644 index 00000000..d2376d81 --- /dev/null +++ b/interface/api/verification/resend.yaml @@ -0,0 +1,34 @@ +post: + tags: [Verification, Auth] + summary: Resend verification code + operationId: verificationResendCode + security: + - bearerAuth: [] + requestBody: + $ref: ./bodies/verification.yaml#/components/requestBodies/VerificationCodeBody + responses: + '202': + description: Verification code resent + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/verification.yaml#/components/schemas/VerificationResponseData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '429': + $ref: ../response/operation.yaml#/components/responses/TooManyRequests + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/api/verification/response/verification.yaml b/interface/api/verification/response/verification.yaml new file mode 100644 index 00000000..121f51f7 --- /dev/null +++ b/interface/api/verification/response/verification.yaml @@ -0,0 +1,26 @@ +components: + schemas: + VerificationResponseData: + type: object + additionalProperties: false + required: + - idempotencyKey + - ttl_seconds + - cooldown_seconds + - target + properties: + idempotencyKey: + type: string + ttl_seconds: + type: integer + format: int32 + cooldown_seconds: + type: integer + format: int32 + target: + type: string + + VerifyResultData: + oneOf: + - $ref: ../../accounts/response/auth.yaml#/components/schemas/LoginData + - $ref: ../../response/response.yaml#/components/schemas/SuccessResultData diff --git a/interface/api/verification/verify.yaml b/interface/api/verification/verify.yaml new file mode 100644 index 00000000..92daba31 --- /dev/null +++ b/interface/api/verification/verify.yaml @@ -0,0 +1,34 @@ +post: + tags: [Verification, Auth] + summary: Verify code and complete pending flow + operationId: verificationVerifyCode + security: + - bearerAuth: [] + requestBody: + $ref: ./bodies/verification.yaml#/components/requestBodies/VerifyCodeBody + responses: + '200': + description: Verification successful + content: + application/json: + schema: + allOf: + - $ref: ../response/response.yaml#/components/schemas/BaseResponse + - type: object + properties: + data: + $ref: ./response/verification.yaml#/components/schemas/VerifyResultData + '400': + $ref: ../response/operation.yaml#/components/responses/BadRequest + '401': + $ref: ../response/operation.yaml#/components/responses/Unauthorized + '403': + $ref: ../response/operation.yaml#/components/responses/Forbidden + '404': + $ref: ../response/operation.yaml#/components/responses/NotFound + '410': + $ref: ../response/operation.yaml#/components/responses/Gone + '409': + $ref: ../response/operation.yaml#/components/responses/Conflict + '500': + $ref: ../response/operation.yaml#/components/responses/InternalServerError diff --git a/interface/doc.html b/interface/doc.html new file mode 100644 index 00000000..e57353d6 --- /dev/null +++ b/interface/doc.html @@ -0,0 +1,15 @@ + + +
+ + +