Connect signup and login verification to email notifications #39
No files matched your search
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
name: review-backend-change
|
||||||
|
description: Review, fix, and validate the complete SXCHNGE backend contribution for a task. Use before reporting completion whenever Go, protobuf, or other backend code under backend/ was added or modified, or when the user requests a backend implementation review.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Review Backend Change
|
||||||
|
|
||||||
|
## Establish the review scope
|
||||||
|
|
||||||
|
1. Read the repository root `AGENTS.md` and `backend/AGENTS.md` completely.
|
||||||
|
2. Inspect repository status and the full backend diff attributable to the
|
||||||
|
current task, including uncommitted and committed changes against the task's
|
||||||
|
base.
|
||||||
|
3. Separate unrelated pre-existing work from the task contribution. Preserve
|
||||||
|
it and do not include it in review fixes.
|
||||||
|
4. Identify changed behavior, public or internal contracts, and expected test
|
||||||
|
coverage before judging individual lines.
|
||||||
|
|
||||||
|
## Review and fix the contribution
|
||||||
|
|
||||||
|
1. Apply every quality requirement in `backend/AGENTS.md` to the entire task diff,
|
||||||
|
not only the most recently edited file.
|
||||||
|
2. Search the repository for canonical protobuf messages, enums, Go types,
|
||||||
|
interfaces, and shared domain definitions before accepting new ones.
|
||||||
|
3. Check project-error usage, cause preservation, cohesion, naming, API and
|
||||||
|
module boundaries, duplication, dead code, and testability.
|
||||||
|
4. Review structured logging at meaningful operational and domain boundaries.
|
||||||
|
Check level selection, context, sensitive-data handling, and duplicate error
|
||||||
|
logging.
|
||||||
|
5. Review success, edge, and failure paths. Add or update focused tests for the
|
||||||
|
changed behavior.
|
||||||
|
6. Fix every in-scope issue found, then re-read the resulting complete backend
|
||||||
|
diff. Repeat until no task-caused finding remains.
|
||||||
|
|
||||||
|
Do not weaken checks, suppress failures, or modify unrelated user work to make
|
||||||
|
validation pass.
|
||||||
|
|
||||||
|
## Validate
|
||||||
|
|
||||||
|
After review fixes are complete, run these commands from the repository root:
|
||||||
|
|
||||||
|
```text
|
||||||
|
make test
|
||||||
|
make lint-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
Then select and run every applicable security command from the change-scoped
|
||||||
|
security completion requirements in the root `AGENTS.md`.
|
||||||
|
|
||||||
|
All commands must succeed before reporting the backend task as complete. If a
|
||||||
|
command fails, determine whether the task caused it and fix in-scope failures.
|
||||||
|
Report an external or environmental blocker with the exact command and failure;
|
||||||
|
never represent blocked validation as successful.
|
||||||
|
|
||||||
|
## Report the result
|
||||||
|
|
||||||
|
Summarize the reviewed backend scope, material fixes made during review, tests
|
||||||
|
added or updated, and the outcome of each required command. Call out contract,
|
||||||
|
migration, rollout, security, or observability implications that remain relevant.
|
||||||
@@ -25,3 +25,7 @@ pnpm-debug.log*
|
|||||||
|
|
||||||
# Local editor configuration
|
# Local editor configuration
|
||||||
/.vscode/
|
/.vscode/
|
||||||
|
|
||||||
|
# Local BFF configuration and build output
|
||||||
|
/backend/config.yml
|
||||||
|
/backend/bff
|
||||||
@@ -74,8 +74,8 @@ repository changes do not require a branch.
|
|||||||
|
|
||||||
## Scoped implementation requirements
|
## Scoped implementation requirements
|
||||||
|
|
||||||
- For backend code under `api/`, read and follow
|
- For backend code under `backend/`, read and follow
|
||||||
[`api/AGENTS.md`](api/AGENTS.md). Before reporting completion, use the
|
[`backend/AGENTS.md`](backend/AGENTS.md). Before reporting completion, use the
|
||||||
[`$review-backend-change`](.agents/skills/review-backend-change/SKILL.md)
|
[`$review-backend-change`](.agents/skills/review-backend-change/SKILL.md)
|
||||||
skill.
|
skill.
|
||||||
- For Dart or Flutter code under `frontend/`, read and follow
|
- For Dart or Flutter code under `frontend/`, read and follow
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
.PHONY: test
|
||||||
|
|
||||||
|
test: test-backend test-frontend
|
||||||
|
|
||||||
.PHONY: test-frontend
|
.PHONY: test-frontend
|
||||||
|
|
||||||
test-frontend:
|
test-frontend:
|
||||||
@@ -15,6 +19,7 @@ test-backend:
|
|||||||
cd backend && go test -race ./...
|
cd backend && go test -race ./...
|
||||||
|
|
||||||
lint-backend:
|
lint-backend:
|
||||||
|
cd backend && go test ./internal/architecture
|
||||||
cd backend && test -z "$$(gofmt -l .)"
|
cd backend && test -z "$$(gofmt -l .)"
|
||||||
cd backend && go vet ./...
|
cd backend && go vet ./...
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# SXCHNGE
|
# SXCHNGE
|
||||||
|
|
||||||
Product repository for the sxchnge public website, Flutter consumer app, reusable
|
Product repository for the sxchnge public website, Flutter consumer app, reusable
|
||||||
packages, and planned backend for frontend (BFF).
|
packages, and a backend for frontend (BFF) bootstrapped from Sendico.
|
||||||
|
|
||||||
## Current state
|
## Current state
|
||||||
|
|
||||||
@@ -11,9 +11,9 @@ with `go_router`. Its interface uses the shared theme's colors and typography.
|
|||||||
|
|
||||||
**Authentication, email verification and analytics use dummy services.** No real
|
**Authentication, email verification and analytics use dummy services.** No real
|
||||||
account or session is created, no email is delivered, and no analytics data is
|
account or session is created, no email is delivered, and no analytics data is
|
||||||
transmitted. The backend has an independent Go operational shell; product services
|
transmitted by those app services. The backend now contains locally owned copies
|
||||||
are not connected. Session/KYC access guards and Sendico integration are not
|
of Sendico’s BFF runtime, auth/session stack and account service. The app is not
|
||||||
implemented.
|
connected to that backend or to Sendico yet.
|
||||||
|
|
||||||
## Repository structure
|
## Repository structure
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ implemented.
|
|||||||
| [`sxchnge_theme`](frontend/packages/sxchnge_theme/README.md) | Reusable light/dark themes and bundled Onest font |
|
| [`sxchnge_theme`](frontend/packages/sxchnge_theme/README.md) | Reusable light/dark themes and bundled Onest font |
|
||||||
| [`sxchnge_auth`](frontend/packages/sxchnge_auth/README.md) | Shared auth contracts, providers, two-factor page and dummy services |
|
| [`sxchnge_auth`](frontend/packages/sxchnge_auth/README.md) | Shared auth contracts, providers, two-factor page and dummy services |
|
||||||
| [`sxchnge_analytics`](frontend/packages/sxchnge_analytics/README.md) | Typed journey events, recorder and bounded in-memory dummy analytics |
|
| [`sxchnge_analytics`](frontend/packages/sxchnge_analytics/README.md) | Typed journey events, recorder and bounded in-memory dummy analytics |
|
||||||
| [`backend/`](backend/README.md) | Independent Go BFF starter, adapted foundations and provider integration plan |
|
| [`backend/`](backend/README.md) | Copied BFF/auth/account foundation and isolated public Sendico contracts |
|
||||||
| [`.agents/skills/`](.agents/skills) | Repository agent skills |
|
| [`.agents/skills/`](.agents/skills) | Repository agent skills |
|
||||||
| [`docs/`](docs/implementation.md) | Implementation records and UX measurement contracts |
|
| [`docs/`](docs/implementation.md) | Implementation records and UX measurement contracts |
|
||||||
|
|
||||||
@@ -144,17 +144,19 @@ usability, accessibility and journey measurement under the repository's UX rules
|
|||||||
|
|
||||||
## Product boundaries
|
## Product boundaries
|
||||||
|
|
||||||
The intended integration is: **consumer app → sxchnge BFF → supported Sendico API**.
|
The integration is: **consumer app → sxchnge BFF → Sendico public HTTP API**.
|
||||||
|
SXCHNGE is one organization in Sendico; its customers are owned locally.
|
||||||
|
|
||||||
- sxchnge will own consumer registration/sessions, onboarding and exchange UX,
|
- sxchnge will own consumer registration/sessions, onboarding and exchange UX,
|
||||||
and mappings to stable, organization-scoped Sendico customer references.
|
and mappings from local customers to organization-scoped platform resources.
|
||||||
- Sendico remains authoritative for payment execution, KYC records and
|
- Sendico remains authoritative for payment execution, KYC records and
|
||||||
verification, policy decisions and limit enforcement.
|
verification, policy decisions and limit enforcement.
|
||||||
- The sxchnge organization, backend integration principal and individual customer
|
- The sxchnge organization, backend integration principal and individual customer
|
||||||
references are distinct identities. Consumers must not share the integration
|
references are distinct identities. Consumers must not share the integration
|
||||||
account's customer identity.
|
account's customer identity.
|
||||||
- The BFF uses a supported provider API. Selected Sendico components may be
|
- The BFF uses only the public HTTP API. Existing BFF/auth/account components
|
||||||
adapted into SXCHNGE-owned code; local Sendico module dependencies are not used.
|
are copied into SXCHNGE-owned code; private transports and sibling module
|
||||||
|
dependencies are not used.
|
||||||
Integration credentials belong in the backend.
|
Integration credentials belong in the backend.
|
||||||
|
|
||||||
Before backend integration, agree on the customer, KYC, eligibility/limits and
|
Before backend integration, agree on the customer, KYC, eligibility/limits and
|
||||||
@@ -234,5 +236,7 @@ gaps and delivery phases. Selected Sendico code has been adapted with recorded
|
|||||||
[provenance](backend/PROVENANCE.md); the projects share no runtime modules.
|
[provenance](backend/PROVENANCE.md); the projects share no runtime modules.
|
||||||
|
|
||||||
Run `make test-backend`, `make lint-backend` or `make run-backend` from the root.
|
Run `make test-backend`, `make lint-backend` or `make run-backend` from the root.
|
||||||
The starter exposes health and unconfigured readiness only. Authentication,
|
The copied runtime installs local authentication transport and initializes its
|
||||||
persistence and live financial operations remain the next implementation phases.
|
account service. Signup/profile endpoints, verification delivery/completion,
|
||||||
|
Flutter HTTP adapters and live Sendico operations remain to be wired. See the
|
||||||
|
[backend run guide](backend/README.md) for local MongoDB configuration.
|
||||||
+92
-12
@@ -1,15 +1,95 @@
|
|||||||
# BFF guidelines
|
# Backend Agent Guidelines
|
||||||
|
|
||||||
Follow root AGENTS.md. This is an independent Go module; Sendico is an external
|
These instructions extend the repository-wide rules in the root `AGENTS.md`
|
||||||
provider, not a local module dependency. Never add sibling-path replacements,
|
and apply whenever a task adds or modifies backend code, including Go and
|
||||||
shared database access or internal Sendico discovery/messaging dependencies.
|
protobuf files under `backend/`.
|
||||||
|
|
||||||
Keep HTTP DTOs/mappers, application models/use cases and provider adapters distinct.
|
Before completing the task, review the entire backend diff produced by the
|
||||||
Resolve ownership from the authenticated SXCHNGE principal and server-side mappings.
|
current task, fix every in-scope issue found, and then perform the required
|
||||||
Only adapters may expose provider transport types internally. Adapted code belongs
|
validation. Use the
|
||||||
to SXCHNGE; record source revision and changes in PROVENANCE.md.
|
[`$review-backend-change`](../.agents/skills/review-backend-change/SKILL.md)
|
||||||
|
skill to perform this completion workflow.
|
||||||
|
|
||||||
Review the complete backend contribution before delivery. Run `make test-backend`
|
## Reuse existing definitions
|
||||||
and `make lint-backend` at the repository root. Add behavioral tests for changed
|
|
||||||
boundaries and failure paths. Errors returned publicly must be stable typed codes;
|
- Search the repository before introducing a protobuf message, enum, Go struct,
|
||||||
never expose raw provider errors, secrets, document contents or credentials.
|
interface, or shared domain type.
|
||||||
|
- Reuse or extend the canonical existing definition when its semantics match.
|
||||||
|
Do not create parallel representations or conversion layers for the same
|
||||||
|
concept without a clear architectural reason.
|
||||||
|
- Avoid naming stutter in packages, types, fields, parameters, and access paths.
|
||||||
|
Each nested name should add meaning instead of repeating its parent context.
|
||||||
|
For example, prefer a concise path such as `payment.Details.ID` over
|
||||||
|
`payment.Payment.PaymentID`.
|
||||||
|
|
||||||
|
## Use the project error model
|
||||||
|
|
||||||
|
- Do not introduce `fmt.Errorf` or `errors.New`. Use the constructors and
|
||||||
|
wrapping helpers in `backend/pkg/merrors`.
|
||||||
|
- Preserve the underlying cause when adding context by using an appropriate
|
||||||
|
`merrors` wrapping helper.
|
||||||
|
- When no suitable project error exists, add the smallest generally useful
|
||||||
|
definition or helper to `backend/pkg/merrors` instead of creating an ad hoc error
|
||||||
|
elsewhere.
|
||||||
|
|
||||||
|
## Keep modules cohesive and names concise
|
||||||
|
|
||||||
|
- Review touched files for excessive size, mixed responsibilities, duplicated
|
||||||
|
logic, and poor separation of concerns.
|
||||||
|
- Refactor oversized contributions into focused, cohesive files or packages.
|
||||||
|
Do not split code mechanically; organize it along clear domain or
|
||||||
|
architectural boundaries.
|
||||||
|
- Avoid repeating directory or package context in child directory and file
|
||||||
|
names. For example, prefer `payment/widget.dart` over
|
||||||
|
`payment/payment_widget.dart`.
|
||||||
|
|
||||||
|
## Review implementation quality
|
||||||
|
|
||||||
|
- Review the current task's backend contribution for correctness, readability,
|
||||||
|
maintainability, testability, and consistency with the surrounding
|
||||||
|
architecture.
|
||||||
|
- Keep public APIs and module boundaries small and intentional. Remove
|
||||||
|
unnecessary indirection, duplication, dead code, and speculative abstractions.
|
||||||
|
- Add or update tests for changed behavior, edge cases, and failure paths.
|
||||||
|
- Fix all findings caused by the current task before reporting completion.
|
||||||
|
|
||||||
|
## Review logging
|
||||||
|
|
||||||
|
- Ensure the contribution has sufficient structured logging at meaningful
|
||||||
|
operational and domain boundaries. Include useful identifiers and context,
|
||||||
|
but never log credentials, secrets, or sensitive payment data.
|
||||||
|
- Follow the repository's logging style and use levels consistently:
|
||||||
|
- `Debug`: fine-grained runtime execution tracking useful during debugging.
|
||||||
|
- `Info`: important payment-domain events, module-boundary operations,
|
||||||
|
effective module configuration, and noteworthy but expected deviations from
|
||||||
|
the usual path.
|
||||||
|
- `Warn`: runtime errors and unexpected conditions from which the service can
|
||||||
|
continue or which are returned to a caller.
|
||||||
|
- `Error`: unrecoverable failures that cause, or imminently lead to, service
|
||||||
|
or component termination.
|
||||||
|
- Avoid logging the same error repeatedly at multiple layers. Log it where the
|
||||||
|
layer has enough context to make the event actionable.
|
||||||
|
|
||||||
|
## Required validation
|
||||||
|
|
||||||
|
- From the repository root, run `make test` and `make lint-backend`, plus every
|
||||||
|
applicable command from the root `AGENTS.md` change-scoped security
|
||||||
|
requirements, after all review fixes are complete.
|
||||||
|
- All commands must succeed before the task is reported as complete. Fix
|
||||||
|
failures introduced by the current task; do not silently skip, suppress, or
|
||||||
|
weaken checks.
|
||||||
|
- Report the commands run and their outcomes in the final response. If an
|
||||||
|
external or environmental blocker prevents a command from running, report
|
||||||
|
the exact command, failure, and blocker explicitly; do not claim successful
|
||||||
|
validation.
|
||||||
|
|
||||||
|
## SXCHNGE provider boundary
|
||||||
|
|
||||||
|
SXCHNGE owns auth, sessions and customer management. SXCHNGE is one organization
|
||||||
|
inside Sendico. Copied BFF components are locally owned and may diverge.
|
||||||
|
Use only Sendico's public HTTP API for platform operations. Never import sibling
|
||||||
|
Sendico modules or access its database, internal gRPC APIs, discovery or message
|
||||||
|
bus. Keep the pinned public wire contract separate from local DTOs and models.
|
||||||
|
Resolve the configured provider organization and customer resource ownership on
|
||||||
|
the server. Never treat all customers as the backend integration principal.
|
||||||
|
Use the copied structured logger, injected at operational boundaries.
|
||||||
File diff suppressed because it is too large.
Load diff
+54
-28
@@ -1,38 +1,64 @@
|
|||||||
# Sendico reuse provenance
|
# Copied Sendico source
|
||||||
|
|
||||||
Source repository: `S_I/sendico`; revision `8bb20dcd622dd8eb92d289b6b34411e7eccab083`.
|
Source repository: `S_I/sendico` (`git.sendico.io`). Revision:
|
||||||
Inspected 2026-09-12. These are owned forks inside SXCHNGE, not runtime imports.
|
`8bb20dcd622dd8eb92d289b6b34411e7eccab083`.
|
||||||
Source files below match the committed revision; local dependency edits were not used.
|
|
||||||
No generated Sendico SDK, shared database models, deployment configuration or credentials were copied.
|
|
||||||
|
|
||||||
## `internal/browser/policy.go`
|
[PROVENANCE.json](PROVENANCE.json) records each copied file, original path and
|
||||||
|
Git blob, plus whether a Go file changed beyond import namespace and formatting.
|
||||||
|
It contains 416 Go source/test files, 112 public OpenAPI files and one adapted policy seed. Sources were
|
||||||
|
read from the pinned commit, not Sendico's dirty working tree. These are owned
|
||||||
|
SXCHNGE copies, not submodules or automatic synchronization links.
|
||||||
|
|
||||||
- Source: [api/edge/shared/auth/browser/browser.go](https://git.sendico.io/S_I/sendico/src/commit/8bb20dcd622dd8eb92d289b6b34411e7eccab083/api/edge/shared/auth/browser/browser.go)
|
## What was retained
|
||||||
- Source Git blob: `3af7b54aea277d91e0d8c3eba9ee84c155f4b624`
|
|
||||||
- Adaptation: Adapted cookie creation/clearing, origin validation and CSRF checks. Replaced Sendico names/errors/env path resolution with explicit SXCHNGE policy; checks do not depend on a client-controlled transport header. Host-only Secure/HttpOnly cookie, Lax same-site navigation, duplicate-cookie rejection and explicit expiry validation.
|
|
||||||
- Tests are SXCHNGE-specific behavioral checks for the adapted boundary.
|
|
||||||
|
|
||||||
## `internal/credential/token.go`
|
- Shared BFF Chi runtime, process/version/logger bootstrap, HTTP middleware,
|
||||||
|
auth transport and response conventions.
|
||||||
|
- Password/account service, local Mongo account/role/policy repositories,
|
||||||
|
transactions and local organization membership.
|
||||||
|
- Verification issuance, expiry, attempt limits, consumption and idempotency;
|
||||||
|
refresh-session rotation/revocation and login rate-limit storage.
|
||||||
|
- Canonical models, `merrors`, structured logging, health and retained tests.
|
||||||
|
- The public OpenAPI 4.2.37 entry point and recursive local schema references,
|
||||||
|
copied into `contracts/sendico` without schema changes (trailing blank lines
|
||||||
|
normalized in three YAML files).
|
||||||
|
|
||||||
- Source: [api/edge/shared/storage/verification/hash.go](https://git.sendico.io/S_I/sendico/src/commit/8bb20dcd622dd8eb92d289b6b34411e7eccab083/api/edge/shared/storage/verification/hash.go)
|
## Deliberate adaptations
|
||||||
- Source Git blob: `36fadcf404bfc77608b28cca1e669a4a62f31774`
|
|
||||||
- Adaptation: Adapted generateMagic/tokenHash only: 32-byte crypto/rand, URL-safe encoding, SHA-256 digest. Added constant-time matching. Excluded deterministic token generation, Sendico models and all numeric OTP hashing.
|
|
||||||
- Tests are SXCHNGE-specific behavioral checks for the adapted boundary.
|
|
||||||
|
|
||||||
## `internal/evidence/key.go`
|
- Import roots now belong to `git.sendico.io/tech/sxchnge/bff`. Versions are seeded
|
||||||
|
from committed Sendico manifests and tidied for the selected dependency set.
|
||||||
|
- Product's composition root selects local account services instead of platform
|
||||||
|
services/provisioning. Its shared HTTP runtime remains the implementation.
|
||||||
|
- Removed internal discovery and broker configuration, registration, startup and
|
||||||
|
teardown. An instance ID uses the existing UUID dependency without discovery.
|
||||||
|
- Excluded internal gRPC/protobuf clients/converters and unused model files.
|
||||||
|
Local account-role values remain; private protobuf conversion helpers do not.
|
||||||
|
- Program identity and the refresh-cookie name use SXCHNGE.
|
||||||
|
- The policy seed retains the existing upsert helpers and three local
|
||||||
|
organization/account/role definitions, with an SXCHNGE database default.
|
||||||
|
Platform policies, automatic role backfills and pruning are excluded.
|
||||||
|
- Startup configuration now rejects missing database/middleware/HTTP settings
|
||||||
|
and invalid HTTP timeouts. Runtime-construction failure closes the database.
|
||||||
|
Listen/start failures preserve the cause and produce a nonzero CLI exit.
|
||||||
|
- Copied Casbin adapter errors and test sentinel errors use canonical `merrors`
|
||||||
|
instead of `errors.New`. Removed raw database settings from error logs.
|
||||||
|
- The recipient-migration-only test was excluded together with its migration:
|
||||||
|
neither that platform feature nor historical Sendico data migration is part of
|
||||||
|
this bootstrap. Tests for every retained runtime/component remain included.
|
||||||
|
|
||||||
- Source: [api/edge/shared/storage/s3key/key.go](https://git.sendico.io/S_I/sendico/src/commit/8bb20dcd622dd8eb92d289b6b34411e7eccab083/api/edge/shared/storage/s3key/key.go)
|
No financial engine, internal service client, gateway, platform organization
|
||||||
- Source Git blob: `e3cca16304d2c4cb9f256f510d5a1a30a21e22a6`
|
provisioning, deployment configuration, credential or generated binary was copied.
|
||||||
- Adaptation: Adapted relative object-key confinement. Replaced merrors with a local sentinel and rejected encoded sequences, backslashes and embedded control characters. Not a filesystem or customer-authorization utility.
|
The local account service's organization is an SXCHNGE authorization tenant;
|
||||||
- Tests are SXCHNGE-specific behavioral checks for the adapted boundary.
|
it does not create Sendico organizations per customer.
|
||||||
|
|
||||||
## Maintenance
|
## Local additions
|
||||||
|
|
||||||
The command, operational HTTP shell, module configuration and tests are new SXCHNGE code.
|
`internal/profile` composes the copied account service. Architecture checks enforce
|
||||||
There is no automatic synchronization or promise of source compatibility with Sendico.
|
project errors, no private provider imports/transports and self-contained public
|
||||||
For an upstream fix, review the pinned source difference, port only the relevant behavior,
|
contract references. Configuration tests cover the executable example and missing
|
||||||
record a new provenance entry and run backend tests/vet. Provider contract changes belong
|
settings. Guidelines and the backend-review skill are restored from Sendico with
|
||||||
in the future Sendico adapter and its transport fixtures, not application models or widgets.
|
SXCHNGE paths and the public-only integration boundary.
|
||||||
|
|
||||||
These primitives do not create sessions, deliver email, validate TOTP or upload documents.
|
The source includes complete local auth building blocks, not a fully wired
|
||||||
Use them inside the durable flows described in the [BFF plan](../docs/architecture/bff.md).
|
SXCHNGE product API. Remaining endpoint, email, local tenant/client provisioning
|
||||||
|
and public Sendico integration work is explicit in the
|
||||||
|
[architecture plan](../docs/architecture/bff.md).
|
||||||
+35
-27
@@ -1,38 +1,46 @@
|
|||||||
# SXCHNGE BFF
|
# SXCHNGE BFF
|
||||||
|
|
||||||
Independent Go module with an operational HTTP shell and selected, adapted
|
A locally owned copy of Sendico's reusable BFF runtime, authentication/session
|
||||||
Sendico foundations. Sendico remains an external financial-services provider;
|
stack and account service. See [provenance](PROVENANCE.md) and the
|
||||||
there are no Sendico module imports, shared databases or sibling-path dependencies.
|
[architecture and public API plan](../docs/architecture/bff.md).
|
||||||
See the [architecture and service plan](../docs/architecture/bff.md) and
|
|
||||||
[reuse provenance](PROVENANCE.md).
|
|
||||||
|
|
||||||
## Run and validate
|
SXCHNGE owns its customers and authentication. SXCHNGE itself is one organization
|
||||||
|
in Sendico. Provider integration uses only Sendico's public HTTP API; the pinned
|
||||||
|
[OpenAPI snapshot](contracts/sendico/api.yaml) is isolated from local models.
|
||||||
|
|
||||||
Requires Go 1.26 or later. From the repository root:
|
## Run locally
|
||||||
|
|
||||||
|
Requires Go 1.27 and an SXCHNGE-owned MongoDB replica set for transactions.
|
||||||
|
Copy `config.example.yml` to an untracked `config.yml`. Set:
|
||||||
|
|
||||||
|
- `SXCHNGE_MONGO_URI`: URI for the local SXCHNGE database.
|
||||||
|
- `SXCHNGE_JWT_SECRET`: private random signing key, at least 32 bytes for HS256.
|
||||||
|
- `SXCHNGE_DOMAIN`: local API hostname (for example `localhost:8082`).
|
||||||
|
- `SXCHNGE_API_PROTOCOL`: `http` locally, `https` in deployment.
|
||||||
|
- `SXCHNGE_API_ENDPOINT`: `/api/v1`.
|
||||||
|
|
||||||
|
Seed the local policy descriptions before first startup (requires `mongosh`):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make test-backend
|
mongosh "$SXCHNGE_MONGO_URI" --file backend/scripts/seed-policies.js
|
||||||
make lint-backend
|
|
||||||
make run-backend
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The default address is `127.0.0.1:8082`; override with `SXCHNGE_HTTP_ADDR`.
|
The seed is repeatable and creates only the three local built-in policy
|
||||||
`GET /healthz` reports process health. `GET /readyz` deliberately returns **503**
|
descriptions required by the copied runtime. It grants no role permissions.
|
||||||
with `not_configured`: persistence, authentication and Sendico are not connected.
|
Run `make run-backend` from the repository root. The copied CLI accepts
|
||||||
No product routes return dummy success. The process handles SIGINT/SIGTERM with
|
`-config.file`, `-version` and `-debug`. Configure exact browser origins in YAML;
|
||||||
bounded graceful shutdown. Production transport must terminate HTTPS.
|
secure refresh cookies require HTTPS for browser session testing.
|
||||||
|
|
||||||
## Present components
|
The runtime mounts `/api/v1/health` and the copied account login, API login,
|
||||||
|
refresh, rotation and logout handlers. Customer/client records must exist in the
|
||||||
|
local database. The account service is initialized locally; signup/profile and
|
||||||
|
verification-delivery/completion routes are the next wiring work. This is a
|
||||||
|
bootstrap, not a finished authentication deployment. No Sendico calls are made.
|
||||||
|
|
||||||
- `cmd/bff`, `internal/httpapi`: HTTP process, timeouts and operational endpoints.
|
## Validate
|
||||||
- `internal/browser`: explicit HTTPS origin/CSRF policy and Secure HttpOnly
|
|
||||||
host-only session cookie. Apply this policy to every future browser mutation;
|
|
||||||
it is not yet connected to product routes because those do not exist.
|
|
||||||
- `internal/credential`: random opaque credentials and storage digests. Never use
|
|
||||||
this helper for passwords or short OTP codes.
|
|
||||||
- `internal/evidence`: confined server-generated object keys; not a substitute
|
|
||||||
for ownership, upload validation or private storage controls.
|
|
||||||
|
|
||||||
Only the standard library is required. Larger adapted flows, persistence,
|
Run `make test` and `make lint-backend`. Backend tests include real MongoDB
|
||||||
provider DTOs/mappers, email and live integration follow the plan in separate
|
integration tests through Testcontainers, so Docker must be running.
|
||||||
contributions. Source-derived components evolve independently inside this repo.
|
`make test-backend` runs the backend suite with the race detector.
|
||||||
|
Architecture checks reject private Sendico imports/transports and ad hoc error
|
||||||
|
constructors. The frontend still uses dummy services; no Flutter source changed.
|
||||||
+11
-36
@@ -1,46 +1,21 @@
|
|||||||
|
// Adapted from Sendico api/edge/product/main.go; see PROVENANCE.md.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"git.sendico.io/tech/sxchnge/bff/edge/shared/appversion"
|
||||||
"errors"
|
"git.sendico.io/tech/sxchnge/bff/edge/shared/server"
|
||||||
"log/slog"
|
"git.sendico.io/tech/sxchnge/bff/internal/profile"
|
||||||
"net/http"
|
"git.sendico.io/tech/sxchnge/bff/pkg/mlogger"
|
||||||
|
application "git.sendico.io/tech/sxchnge/bff/pkg/server"
|
||||||
|
smain "git.sendico.io/tech/sxchnge/bff/pkg/server/main"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.sendico.io/tech/sxchnge/bff/internal/httpapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func factory(logger mlogger.Logger, file string, debug bool) (application.Application, error) {
|
||||||
|
return server.Create(logger, file, debug, profile.Runtime())
|
||||||
|
}
|
||||||
func main() {
|
func main() {
|
||||||
if err := run(); err != nil {
|
if smain.RunServer("sxchnge.bff", appversion.Create(), factory) != nil {
|
||||||
slog.Error("BFF stopped", "error", err)
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
|
||||||
addr := os.Getenv("SXCHNGE_HTTP_ADDR")
|
|
||||||
if addr == "" {
|
|
||||||
addr = "127.0.0.1:8082"
|
|
||||||
}
|
|
||||||
server := &http.Server{Addr: addr, Handler: httpapi.New(), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 1 << 20}
|
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
||||||
defer stop()
|
|
||||||
failures := make(chan error, 1)
|
|
||||||
go func() { failures <- server.ListenAndServe() }()
|
|
||||||
slog.Info("BFF operational shell starting", "address", addr, "provider_configured", false)
|
|
||||||
select {
|
|
||||||
case err := <-failures:
|
|
||||||
if errors.Is(err, http.ErrServerClosed) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
case <-ctx.Done():
|
|
||||||
shutdown, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
slog.Info("BFF shutting down")
|
|
||||||
return server.Shutdown(shutdown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# SXCHNGE-owned Mongo database and JWT key. Never point these at Sendico.
|
||||||
|
http_server:
|
||||||
|
listen_address: 127.0.0.1:8082
|
||||||
|
read_header_timeout: 5
|
||||||
|
shutdown_timeout: 10
|
||||||
|
database:
|
||||||
|
driver: mongodb
|
||||||
|
settings:
|
||||||
|
uri_env: SXCHNGE_MONGO_URI
|
||||||
|
database: sxchnge
|
||||||
|
enforcer:
|
||||||
|
driver: native
|
||||||
|
api:
|
||||||
|
middleware:
|
||||||
|
domain_env: SXCHNGE_DOMAIN
|
||||||
|
api_endpoint_env: SXCHNGE_API_ENDPOINT
|
||||||
|
api_protocol_env: SXCHNGE_API_PROTOCOL
|
||||||
|
signature:
|
||||||
|
algorithm: HS256
|
||||||
|
secret_key_env: SXCHNGE_JWT_SECRET
|
||||||
|
CORS:
|
||||||
|
allowed_origins: ["http://localhost:5126"]
|
||||||
|
allowed_methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"]
|
||||||
|
allowed_headers: ["Content-Type", "Authorization", "X-Auth-Transport", "X-CSRF-Protection"]
|
||||||
|
allow_credentials: true
|
||||||
|
max_age: 300
|
||||||
|
token:
|
||||||
|
expiration_hours:
|
||||||
|
account: 1
|
||||||
|
refresh: 720
|
||||||
|
length: 32
|
||||||
|
password:
|
||||||
|
token_length: 32
|
||||||
|
check:
|
||||||
|
min_length: 12
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
openapi: 3.1.0
|
||||||
|
info:
|
||||||
|
title: Sendico API Contract
|
||||||
|
version: 4.2.37
|
||||||
|
summary: Minimal client contract for authenticated BFF flows.
|
||||||
|
description: |
|
||||||
|
OpenAPI 3.1 contract focused on authenticated client flows exposed by the BFF:
|
||||||
|
authentication, verification, recipients, payment methods, payments, wallets,
|
||||||
|
and ledger account history.
|
||||||
|
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: Payment Methods
|
||||||
|
description: Payment method CRUD and archive flows
|
||||||
|
- name: Callbacks
|
||||||
|
description: Webhook callback subscription CRUD and signing material rotation for HMAC and detached-JWS callbacks
|
||||||
|
- name: Payments
|
||||||
|
description: Quotation and payment orchestration
|
||||||
|
- name: Wallets
|
||||||
|
description: Managed wallet metadata and balances
|
||||||
|
- name: Ledger Accounts
|
||||||
|
description: Ledger account balances and account-history operations
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/accounts/login:
|
||||||
|
$ref: ./api/accounts/auth_login.yaml
|
||||||
|
/accounts/login/api:
|
||||||
|
$ref: ./api/accounts/auth_login_api.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/accounts/{organizations_ref}/{accounts_ref}:
|
||||||
|
$ref: ./api/payment_methods/accounts.yaml
|
||||||
|
/payment_methods/recipients/{organizations_ref}/{recipients_ref}:
|
||||||
|
$ref: ./api/payment_methods/recipients.yaml
|
||||||
|
/payment_methods/{organizations_ref}/{payment_methods_ref}:
|
||||||
|
$ref: ./api/payment_methods/object.yaml
|
||||||
|
/payment_methods/archive/{organizations_ref}/{payment_methods_ref}:
|
||||||
|
$ref: ./api/payment_methods/archive.yaml
|
||||||
|
|
||||||
|
/callbacks/list/{org_ref}/{organizations_ref}:
|
||||||
|
$ref: ./api/callbacks/list.yaml
|
||||||
|
/callbacks/{org_ref}:
|
||||||
|
$ref: ./api/callbacks/create.yaml
|
||||||
|
/callbacks/{callbacks_ref}:
|
||||||
|
$ref: ./api/callbacks/object.yaml
|
||||||
|
/callbacks:
|
||||||
|
$ref: ./api/callbacks/update.yaml
|
||||||
|
/callbacks/archive/{org_ref}/{callbacks_ref}:
|
||||||
|
$ref: ./api/callbacks/archive.yaml
|
||||||
|
/callbacks/rotate-secret/{callbacks_ref}:
|
||||||
|
$ref: ./api/callbacks/rotate_secret.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/by-ref/{payments_ref}:
|
||||||
|
$ref: ./api/payments/object.yaml
|
||||||
|
/payments/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/list.yaml
|
||||||
|
/payments/documents/certificate/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/documents_certificate.yaml
|
||||||
|
/payments/registry/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/registry.yaml
|
||||||
|
/payments/registry/refresh/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/registry_refresh.yaml
|
||||||
|
/payments/fx/currencies/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/fx_currencies.yaml
|
||||||
|
/payments/fx/directions/{organizations_ref}:
|
||||||
|
$ref: ./api/payments/fx_directions.yaml
|
||||||
|
/chain_wallets/{organizations_ref}/assets:
|
||||||
|
$ref: ./api/wallets/assets.yaml
|
||||||
|
/ledger_accounts/{organizations_ref}/{ledger_account_ref}/balance:
|
||||||
|
$ref: ./api/ledger_accounts/balance.yaml
|
||||||
|
/ledger_accounts/{organizations_ref}/{ledger_account_ref}/operations:
|
||||||
|
$ref: ./api/ledger_accounts/operations.yaml
|
||||||
|
/ledger_accounts/{organizations_ref}/{ledger_account_ref}/operations/{entry_ref}:
|
||||||
|
$ref: ./api/ledger_accounts/operation.yaml
|
||||||
|
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
bearerAuth:
|
||||||
|
type: http
|
||||||
|
scheme: bearer
|
||||||
|
bearerFormat: JWT
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
post:
|
||||||
|
tags: [Accounts, Auth]
|
||||||
|
summary: Login using email/password and receive pending verification token
|
||||||
|
description: |
|
||||||
|
Validates account credentials and returns a short-lived `pendingToken`.
|
||||||
|
This endpoint does not return final access/refresh tokens; complete verification flow via `/verification/verify`.
|
||||||
|
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
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
post:
|
||||||
|
tags: [Accounts, Auth]
|
||||||
|
summary: API login using email/password and client credentials
|
||||||
|
description: |
|
||||||
|
Validates account credentials and eligible API client credentials, then returns final auth payload.
|
||||||
|
This endpoint bypasses login OTP/2FA and is intended only for approved API clients.
|
||||||
|
If the client definition includes `allowedCIDRs`, request source IP must match one of those CIDRs.
|
||||||
|
operationId: accountsApiLogin
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/auth.yaml#/components/requestBodies/ApiLoginBody
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Login successful
|
||||||
|
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
|
||||||
|
'500':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/InternalServerError
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
post:
|
||||||
|
tags: [Accounts, Auth]
|
||||||
|
summary: Refresh access token by refresh token
|
||||||
|
description: |
|
||||||
|
Validates refresh token + session identifiers and issues a new access token.
|
||||||
|
Use this endpoint when refresh token stays the same.
|
||||||
|
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
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
post:
|
||||||
|
tags: [Accounts, Auth]
|
||||||
|
summary: Rotate refresh token and issue new access/refresh tokens
|
||||||
|
description: |
|
||||||
|
Validates refresh token + session identifiers and returns a new token pair.
|
||||||
|
Use this endpoint when replacing both access and 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
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
LoginBody:
|
||||||
|
description: JSON credentials payload for standard login.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/auth.yaml#/components/schemas/LoginRequest
|
||||||
|
ApiLoginBody:
|
||||||
|
description: JSON credentials payload for API client login.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/auth.yaml#/components/schemas/ApiLoginRequest
|
||||||
|
|
||||||
|
RefreshTokenBody:
|
||||||
|
description: JSON payload containing session and refresh token data.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/auth.yaml#/components/schemas/RefreshTokenRequest
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
LoginRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- login
|
||||||
|
properties:
|
||||||
|
clientId:
|
||||||
|
type: string
|
||||||
|
description: Client identifier bound to refresh token lifecycle and client policy checks.
|
||||||
|
deviceId:
|
||||||
|
type: string
|
||||||
|
description: Device/server identifier associated with the client session.
|
||||||
|
login:
|
||||||
|
$ref: ../../../models/auth/login_data.yaml#/components/schemas/LoginData
|
||||||
|
|
||||||
|
ApiLoginRequest:
|
||||||
|
allOf:
|
||||||
|
- $ref: ./auth.yaml#/components/schemas/LoginRequest
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- deviceId
|
||||||
|
- clientSecret
|
||||||
|
properties:
|
||||||
|
clientSecret:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
description: Client secret for `client_secret_post` authentication.
|
||||||
|
|
||||||
|
RefreshTokenRequest:
|
||||||
|
$ref: ../../../models/auth/client_refresh_token.yaml#/components/schemas/ClientRefreshToken
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
AccountAuthData:
|
||||||
|
description: Authentication response containing account profile and access token.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- account
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Access token used for authenticated requests.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
account:
|
||||||
|
description: Authenticated account data.
|
||||||
|
$ref: ../../../models/account/account.yaml#/components/schemas/AccountData
|
||||||
|
|
||||||
|
LoginData:
|
||||||
|
description: Full login response including access and refresh tokens.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- account
|
||||||
|
- refreshToken
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Access token used for authenticated requests.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
account:
|
||||||
|
description: Authenticated account data.
|
||||||
|
$ref: ../../../models/account/account.yaml#/components/schemas/AccountData
|
||||||
|
refreshToken:
|
||||||
|
description: Refresh token used to obtain a new access token.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
|
||||||
|
PendingLoginData:
|
||||||
|
description: Pending login response requiring additional verification.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- account
|
||||||
|
- pendingToken
|
||||||
|
- target
|
||||||
|
properties:
|
||||||
|
account:
|
||||||
|
description: Interim authentication payload prepared for verification completion.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Temporary access token issued before verification is completed.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
account:
|
||||||
|
description: Account data associated with the pending login flow.
|
||||||
|
$ref: ../../../models/account/account.yaml#/components/schemas/AccountData
|
||||||
|
pendingToken:
|
||||||
|
description: Token proving the pending verification session.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
target:
|
||||||
|
description: Verification target destination (for example email or phone).
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
get:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: Archive/unarchive callback subscription
|
||||||
|
description: Sets callback archive state by `callbacks_ref` and required `archived` query parameter.
|
||||||
|
operationId: callbacksArchive
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef
|
||||||
|
- $ref: ../parameters/callbacks_ref.yaml#/components/parameters/CallbacksRef
|
||||||
|
- name: archived
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: Target archive value to set on the callback.
|
||||||
|
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/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
CallbackCreateBody:
|
||||||
|
description: JSON body containing callback endpoint configuration for create.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/callback.yaml#/components/schemas/CallbackCreateRequest
|
||||||
|
|
||||||
|
CallbackUpdateBody:
|
||||||
|
description: JSON body containing callback endpoint configuration for update.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/callback.yaml#/components/schemas/CallbackUpdateRequest
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
post:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: Create callback subscription
|
||||||
|
description: Creates callback subscription for the organization identified by `org_ref`.
|
||||||
|
operationId: callbacksCreate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/callback.yaml#/components/requestBodies/CallbackCreateBody
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Callback created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
get:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: List callback subscriptions
|
||||||
|
description: |
|
||||||
|
Lists callbacks for the given organization context.
|
||||||
|
The route currently includes both `org_ref` and `organizations_ref`; the handler resolves organization context from `org_ref` and ignores `organizations_ref`.
|
||||||
|
operationId: callbacksList
|
||||||
|
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: Callback list
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
get:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: Get callback subscription
|
||||||
|
description: Returns callback subscription by `callbacks_ref`.
|
||||||
|
operationId: callbacksGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/callbacks_ref.yaml#/components/parameters/CallbacksRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Callback data
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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: [Callbacks]
|
||||||
|
summary: Delete callback subscription
|
||||||
|
description: Deletes callback by reference.
|
||||||
|
operationId: callbacksDelete
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/callbacks_ref.yaml#/components/parameters/CallbacksRef
|
||||||
|
- $ref: ../parameters/cascade.yaml#/components/parameters/Cascade
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Callback deleted
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
CallbackBackoffInput:
|
||||||
|
description: Optional retry backoff overrides. Non-positive values currently fall back to server defaults.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
minDelayMs:
|
||||||
|
type: integer
|
||||||
|
maxDelayMs:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
CallbackRetryPolicyInput:
|
||||||
|
description: Optional retry and signing overrides. Omitted or non-positive numeric values currently fall back to server defaults.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
backoff:
|
||||||
|
$ref: '#/components/schemas/CallbackBackoffInput'
|
||||||
|
signingMode:
|
||||||
|
description: |
|
||||||
|
Optional signing mode. Canonical values are documented here; current handler also accepts legacy aliases such as `hmac`, `hmac-sha256`, `jws-eddsa-ed25519`, `jws+eddsa-ed25519`, `jws_eddsa`, and `eddsa_ed25519`.
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- none
|
||||||
|
- hmac_sha256
|
||||||
|
- jws_eddsa_ed25519
|
||||||
|
headers:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
maxAttempts:
|
||||||
|
type: integer
|
||||||
|
requestTimeoutMs:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
CallbackCreateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to create a callback configuration.
|
||||||
|
Only `url` is hard-required by current create logic. Other mutable fields are optional and defaulted by the handler when omitted.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- url
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Optional callback display name. When omitted, the handler defaults it to `url`.
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
description: Optional callback description.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
status:
|
||||||
|
description: |
|
||||||
|
Optional callback status. Canonical values are documented here; current handler also accepts `enabled` and `inactive` aliases.
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- active
|
||||||
|
- disabled
|
||||||
|
url:
|
||||||
|
description: Absolute HTTPS callback endpoint URL.
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
eventTypes:
|
||||||
|
description: Optional callback event types. When omitted or empty, the handler defaults this list.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
retryPolicy:
|
||||||
|
$ref: '#/components/schemas/CallbackRetryPolicyInput'
|
||||||
|
|
||||||
|
CallbackUpdateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to update a callback configuration.
|
||||||
|
The current PUT handler requires `id`, `organizationRef`, and `url`. Other mutable fields are optional, but omitted values may be reset to handler defaults during normalization.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- organizationRef
|
||||||
|
- url
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: Callback identifier to update.
|
||||||
|
$ref: ../../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
|
organizationRef:
|
||||||
|
description: Organization identifier carried in the stored callback record and currently required by the update path.
|
||||||
|
$ref: ../../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
|
name:
|
||||||
|
description: Optional callback display name. When omitted, the handler defaults it to `url`.
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
description: Optional callback description.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
status:
|
||||||
|
description: |
|
||||||
|
Optional callback status. Canonical values are documented here; current handler also accepts `enabled` and `inactive` aliases.
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- active
|
||||||
|
- disabled
|
||||||
|
url:
|
||||||
|
description: Absolute HTTPS callback endpoint URL.
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
eventTypes:
|
||||||
|
description: Optional callback event types. When omitted or empty, the handler defaults this list.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
retryPolicy:
|
||||||
|
$ref: '#/components/schemas/CallbackRetryPolicyInput'
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
CallbacksAuthData:
|
||||||
|
description: Authenticated response payload containing callback configurations.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- callbacks
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
callbacks:
|
||||||
|
description: Collection of callbacks configured for the authenticated scope. JWS-signed callbacks expose read-only verification JWKs via `callbacks[].signingKeys`.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/callback/callback.yaml#/components/schemas/Callback
|
||||||
|
generatedSigningSecret:
|
||||||
|
description: Newly generated signing secret when HMAC signing material is created or rotated. JWS-signed callbacks do not populate this field.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
post:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: Rotate callback signing material
|
||||||
|
description: Rotates the active signing material for the callback. HMAC callbacks generate and return a new shared secret once. `jws_eddsa_ed25519` callbacks generate a new Ed25519 keypair, expose the new active verification JWK on normal callback reads, and keep retiring verification keys visible for 24 hours.
|
||||||
|
operationId: callbacksRotateSecret
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/callbacks_ref.yaml#/components/parameters/CallbacksRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Callback signing material rotated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
put:
|
||||||
|
tags: [Callbacks]
|
||||||
|
summary: Update callback subscription
|
||||||
|
description: Updates callback subscription fields. The current handler requires `id`, `organizationRef`, and `url`; omitted mutable fields may be reset to defaults.
|
||||||
|
operationId: callbacksUpdate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/callback.yaml#/components/requestBodies/CallbackUpdateBody
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Callback updated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/callback.yaml#/components/schemas/CallbacksAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
get:
|
||||||
|
tags: [Ledger Accounts]
|
||||||
|
summary: Get ledger account balance
|
||||||
|
description: |
|
||||||
|
Returns the canonical balance for the requested ledger account.
|
||||||
|
|
||||||
|
Without `as_of`, the response is the current materialized balance and includes
|
||||||
|
current metadata fields `version` and `lastUpdated`.
|
||||||
|
|
||||||
|
With `as_of`, the response is an event-time accounting balance reconstructed
|
||||||
|
from posted statement-entry deltas where `eventTime <= as_of`. Entries exactly
|
||||||
|
equal to `as_of` are included. This is not a historical snapshot of materialized
|
||||||
|
balance state and not "what the system knew" at that clock time. Late or
|
||||||
|
backdated postings with older `eventTime` can change historical responses for
|
||||||
|
the same `as_of`. Historical responses include `ledgerAccountRef`, `balance`,
|
||||||
|
and canonical UTC `asOf`, and omit `version` and `lastUpdated` because no
|
||||||
|
historical snapshot/version semantics are defined.
|
||||||
|
|
||||||
|
Historical balance is valid only if every account-affecting committed posting
|
||||||
|
writes matching statement entries in the same transaction as balance updates.
|
||||||
|
operationId: ledgerAccountBalanceGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/ledger_account_ref.yaml#/components/parameters/LedgerAccountRef
|
||||||
|
- name: as_of
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Optional RFC3339 event-time cutoff for historical balance reconstruction.
|
||||||
|
Timezone offsets are accepted and returned as canonical UTC `asOf`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
example: '2026-04-23T14:30:00+02:00'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Ledger account balance
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/balance.yaml#/components/schemas/LedgerAccountBalanceData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
get:
|
||||||
|
tags: [Ledger Accounts]
|
||||||
|
summary: Get ledger account operation detail
|
||||||
|
description: |
|
||||||
|
Returns the account-history projection for `entry_ref` within the requested ledger account.
|
||||||
|
This is not a general journal-entry read API.
|
||||||
|
The endpoint returns `404` when the entry is not part of the requested account's visible history.
|
||||||
|
operationId: ledgerAccountOperationsGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/ledger_account_ref.yaml#/components/parameters/LedgerAccountRef
|
||||||
|
- $ref: ../parameters/entry_ref.yaml#/components/parameters/EntryRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Ledger account operation detail
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/operation.yaml#/components/schemas/LedgerAccountOperationData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
get:
|
||||||
|
tags: [Ledger Accounts]
|
||||||
|
summary: List ledger account operations
|
||||||
|
description: |
|
||||||
|
Returns account-history summary projections for the requested ledger account.
|
||||||
|
Public HTTP pagination supports only `limit` and `offset`.
|
||||||
|
Results are ordered by `version` descending and `entry_ref` descending.
|
||||||
|
Unsupported query parameters, including `archived`, are rejected.
|
||||||
|
operationId: ledgerAccountOperationsList
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/ledger_account_ref.yaml#/components/parameters/LedgerAccountRef
|
||||||
|
- $ref: ../parameters/limit.yaml#/components/parameters/Limit
|
||||||
|
- $ref: ../parameters/offset.yaml#/components/parameters/Offset
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Ledger account operation summaries
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/operation.yaml#/components/schemas/LedgerAccountOperationsData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
LedgerAccountBalanceData:
|
||||||
|
description: Response payload containing a ledger account balance.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- balance
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
balance:
|
||||||
|
$ref: ../../../models/ledger/balance.yaml#/components/schemas/LedgerAccountBalance
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
LedgerAccountOperationsData:
|
||||||
|
description: Response payload containing ledger account history summaries.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- operations
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
operations:
|
||||||
|
description: Account-history summaries ordered by `version DESC, entryRef DESC`.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/ledger/operation.yaml#/components/schemas/LedgerAccountOperationSummary
|
||||||
|
|
||||||
|
LedgerAccountOperationData:
|
||||||
|
description: Response payload containing a single ledger account history projection.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- operation
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
operation:
|
||||||
|
description: Account-history projection for the requested entry and ledger account.
|
||||||
|
$ref: ../../../models/ledger/operation.yaml#/components/schemas/LedgerAccountOperation
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
get:
|
||||||
|
tags: [Organizations]
|
||||||
|
summary: Get organization by reference
|
||||||
|
description: Fetches a single organization available to the authenticated account.
|
||||||
|
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
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OrganizationsAuthData:
|
||||||
|
description: Authenticated response payload containing organizations.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- organizations
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
organizations:
|
||||||
|
description: Collection of organizations available to the authenticated account.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/organization/organization.yaml#/components/schemas/Organization
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
get:
|
||||||
|
tags: [Organizations]
|
||||||
|
summary: List organizations of current account
|
||||||
|
description: Returns organizations the authenticated account can access.
|
||||||
|
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
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
AccountsRef:
|
||||||
|
name: accounts_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Account reference, 24 hex chars.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Archived:
|
||||||
|
name: archived
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Filter by archive flag. `true` returns archived records, `false` returns active records.
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
CallbacksRef:
|
||||||
|
name: callbacks_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Callback subscription reference, 24 hex chars.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Cascade:
|
||||||
|
name: cascade
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: If `true`, apply operation to dependent objects where cascade is supported.
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Cursor:
|
||||||
|
name: cursor
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Opaque cursor from a previous page response (`page.next_cursor`).
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
EntryRef:
|
||||||
|
name: entry_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Statement entry reference within the requested ledger account history.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
FilterStates:
|
||||||
|
name: filter_states
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Additional payment state filter. Accepts one value or comma-separated values.
|
||||||
|
Same semantics as `state`/`states`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
LedgerAccountRef:
|
||||||
|
name: ledger_account_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Ledger account reference that scopes the account-history read.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Limit:
|
||||||
|
name: limit
|
||||||
|
in: query
|
||||||
|
description: Max number of items to return. Parsed as non-negative int64.
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Offset:
|
||||||
|
name: offset
|
||||||
|
in: query
|
||||||
|
description: Number of items to skip. Parsed as non-negative int64.
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
OrgRef:
|
||||||
|
name: org_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Organization reference in BFF route format, 24 hex chars.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
OrganizationsRef:
|
||||||
|
name: organizations_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Organization reference used by payments/payment-methods/recipients routes.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
Payment MethodsRef:
|
||||||
|
name: payment_methods_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Payment method reference, 24 hex chars.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
PaymentsRef:
|
||||||
|
name: payments_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Stable payment reference.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
RecipientsRef:
|
||||||
|
name: recipients_ref
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Recipient reference, 24 hex chars.
|
||||||
|
schema:
|
||||||
|
$ref: ../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
State:
|
||||||
|
name: state
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Payment state filter. Accepts aliases like `accepted`, `settled`, `failed`
|
||||||
|
or canonical values like `orchestration_state_created`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
States:
|
||||||
|
name: states
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Multi-state filter. Provide a comma-separated list with same accepted values as `state`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: List account-owned payment methods
|
||||||
|
description: |
|
||||||
|
Returns payment methods owned by `accounts_ref` within `organizations_ref`.
|
||||||
|
Supports offset pagination and optional archive filtering.
|
||||||
|
operationId: paymentMethodsListAccountOwned
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/accounts_ref.yaml#/components/parameters/AccountsRef
|
||||||
|
- $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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
|
|
||||||
|
post:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Create account-owned payment method
|
||||||
|
description: Creates a payment method owned by `accounts_ref` inside `organizations_ref`.
|
||||||
|
operationId: paymentMethodsCreateAccountOwned
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/accounts_ref.yaml#/components/parameters/AccountsRef
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/payment_method.yaml#/components/requestBodies/PaymentMethodCreateBody
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Archive/unarchive payment method
|
||||||
|
description: Sets payment method archive state by `payment_methods_ref` and required `archived` query parameter.
|
||||||
|
operationId: paymentMethodsArchive
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/Payment MethodsRef
|
||||||
|
- name: archived
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: Target archive value to set on the payment method.
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
PaymentMethodCreateBody:
|
||||||
|
description: JSON body containing a payment method definition for create.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment_method.yaml#/components/schemas/PaymentMethodCreateRequest
|
||||||
|
|
||||||
|
PaymentMethodUpdateBody:
|
||||||
|
description: JSON body containing a payment method definition for update.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment_method.yaml#/components/schemas/PaymentMethodUpdateRequest
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Get payment method
|
||||||
|
description: Returns payment method by `payment_methods_ref` inside `organizations_ref`.
|
||||||
|
operationId: paymentMethodsGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/Payment MethodsRef
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
|
|
||||||
|
patch:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Update payment method
|
||||||
|
description: Updates mutable payment method fields for the record identified by `payment_methods_ref` inside `organizations_ref`.
|
||||||
|
operationId: paymentMethodsUpdate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/Payment MethodsRef
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/payment_method.yaml#/components/requestBodies/PaymentMethodUpdateBody
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
|
|
||||||
|
delete:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Delete payment method
|
||||||
|
description: Deletes payment method by reference.
|
||||||
|
operationId: paymentMethodsDelete
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/payment_methods_ref.yaml#/components/parameters/Payment MethodsRef
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: List recipient-owned payment methods
|
||||||
|
description: |
|
||||||
|
Returns payment methods owned by `recipients_ref` within `organizations_ref`.
|
||||||
|
Supports offset pagination and optional archive filtering.
|
||||||
|
operationId: paymentMethodsListRecipientOwned
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
|
|
||||||
|
post:
|
||||||
|
tags: [Payment Methods]
|
||||||
|
summary: Create recipient-owned payment method
|
||||||
|
description: Creates a payment method owned by `recipients_ref` inside `organizations_ref`.
|
||||||
|
operationId: paymentMethodsCreateRecipientOwned
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- $ref: ../parameters/recipients_ref.yaml#/components/parameters/RecipientsRef
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/payment_method.yaml#/components/requestBodies/PaymentMethodCreateBody
|
||||||
|
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/Payment MethodsAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PaymentMethodBaseRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Optional human-readable payment method name.
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
description: Optional free-form payment method description.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
type:
|
||||||
|
description: Payment method type discriminator.
|
||||||
|
$ref: ../../../external/payment_method_type.yaml#/components/schemas/PaymentMethodType
|
||||||
|
data:
|
||||||
|
description: |
|
||||||
|
Optional payment-method-type-specific payload.
|
||||||
|
For `type: bankAccount`, this uses the Russian bank-account
|
||||||
|
destination shape documented as `BankAccountEndpoint`.
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
isMain:
|
||||||
|
description: Optional primary-method flag. When omitted, current handler behavior falls back to `false`.
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
PaymentMethodCreateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to create a payment method.
|
||||||
|
Ownership comes from the route path. The body only carries mutable payment-method fields.
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/PaymentMethodBaseRequest'
|
||||||
|
|
||||||
|
PaymentMethodUpdateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to update a payment method.
|
||||||
|
This is a PATCH contract. Only `name`, `description`, `data`, and `isMain` are mutable.
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/PaymentMethodBaseRequest'
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Payment MethodsAuthData:
|
||||||
|
description: Authenticated response payload containing payment methods.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- payment_methods
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
payment_methods:
|
||||||
|
description: Collection of payment methods available to the authenticated account.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment_method/payment_method.yaml#/components/schemas/PaymentMethod
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
QuotePaymentBody:
|
||||||
|
description: JSON payload used to request a quote for one payment intent.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment.yaml#/components/schemas/QuotePaymentRequest
|
||||||
|
|
||||||
|
QuotePaymentsBody:
|
||||||
|
description: JSON payload used to request quotes for multiple payment intents.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment.yaml#/components/schemas/QuotePaymentsRequest
|
||||||
|
|
||||||
|
InitiatePaymentBody:
|
||||||
|
description: JSON payload used to initiate a single payment.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment.yaml#/components/schemas/InitiatePaymentRequest
|
||||||
|
|
||||||
|
InitiatePaymentsBody:
|
||||||
|
description: JSON payload used to initiate multiple payments from a quote reference.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/payment.yaml#/components/schemas/InitiatePaymentsRequest
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Initiate payment batch by quote reference
|
||||||
|
description: |
|
||||||
|
Executes batch payment from a previously created multi-quote reference. If any quoted item
|
||||||
|
uses a raw `card` destination, that item's original quote must already include `exp_month`
|
||||||
|
and `exp_year`. Card-recipient AML screening occurs during execution, not quotation. An
|
||||||
|
unchanged payment item reuses its persisted compliance decision on idempotent execution
|
||||||
|
replay, avoiding a duplicate AML call. A definitive denial terminates that payment with
|
||||||
|
public `failureCode: failure_restriction` and `failureReason: aml_denied`.
|
||||||
|
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
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Initiate payment using quote reference
|
||||||
|
description: |
|
||||||
|
Executes one payment from an existing quote reference. If the quoted destination is raw
|
||||||
|
`card`, the original quote must already include `exp_month` and `exp_year`. Card-recipient
|
||||||
|
AML screening occurs during execution, not quotation. An unchanged payment reuses its
|
||||||
|
persisted compliance decision on idempotent execution replay, avoiding a duplicate AML call.
|
||||||
|
A definitive denial terminates the payment with public `failureCode: failure_restriction`
|
||||||
|
and `failureReason: aml_denied`.
|
||||||
|
operationId: paymentsInitiateByQuote
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ./request/payment.yaml#/components/schemas/InitiatePaymentByQuoteRequest
|
||||||
|
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
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Download payment certificate
|
||||||
|
description: |
|
||||||
|
Returns a generated payment certificate as binary content.
|
||||||
|
The payment must be settled; the BFF resolves certificate details from the payment reference.
|
||||||
|
operationId: paymentsGetPaymentCertificate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
- name: payment_ref
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: Settled payment reference used to generate the payment certificate.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Payment certificate file
|
||||||
|
content:
|
||||||
|
application/pdf:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
application/octet-stream:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
'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
|
||||||
|
'503':
|
||||||
|
description: Upstream service unavailable
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../response/response.yaml#/components/schemas/ErrorResponse
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: List available FX currencies
|
||||||
|
description: |
|
||||||
|
Returns the BFF startup-cached Treasury Currency Catalog projection for
|
||||||
|
client-visible FX currencies. `decimals`, `scale`, and `displayScale` are
|
||||||
|
presentation fields backed by Treasury `display_scale`.
|
||||||
|
`accountingScaleCandidate` is informational only and must not be used by
|
||||||
|
clients to determine executable payout precision, quote precision, or
|
||||||
|
guaranteed provider support.
|
||||||
|
The endpoint is authenticated and authorized by `organizations_ref`, but the
|
||||||
|
returned catalogue is global rather than organization-customized. If Treasury
|
||||||
|
was unavailable at BFF startup while this endpoint was enabled, BFF fails
|
||||||
|
startup; if Treasury becomes unavailable after startup, BFF continues serving
|
||||||
|
the cached catalog revision.
|
||||||
|
operationId: paymentsFXCurrencies
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: FX currency catalogue projected from Treasury
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/payment.yaml#/components/schemas/FXCurrenciesData
|
||||||
|
'400':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/BadRequest
|
||||||
|
'401':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/Unauthorized
|
||||||
|
'403':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/Forbidden
|
||||||
|
'503':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/ServiceUnavailable
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: List available FX directions
|
||||||
|
description: |
|
||||||
|
Returns organization-level FX direction availability.
|
||||||
|
|
||||||
|
A returned direction means the organization has at least one eligible
|
||||||
|
direction-level route. It does not mean that every quote or payment for this
|
||||||
|
direction will be accepted. The actual route, gateway, limits, pricing, fees,
|
||||||
|
asset domain, and settlement details are resolved during quotation/payment
|
||||||
|
execution.
|
||||||
|
|
||||||
|
If dependencies are healthy but no organization-eligible executable
|
||||||
|
directions match oracle quoteable pair sides, the response contains an empty
|
||||||
|
`directions` array. Oracle or gateway/route registry dependency failures are
|
||||||
|
returned as errors and are not converted to oracle-only or empty successful
|
||||||
|
responses.
|
||||||
|
operationId: paymentsFXDirections
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Organization-level directed FX availability
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/payment.yaml#/components/schemas/FXDirectionsData
|
||||||
|
'400':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/BadRequest
|
||||||
|
'401':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/Unauthorized
|
||||||
|
'403':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/Forbidden
|
||||||
|
'412':
|
||||||
|
description: Dependency precondition failed
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../response/response.yaml#/components/schemas/ErrorResponse
|
||||||
|
'503':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/ServiceUnavailable
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Initiate payment from immediate intent
|
||||||
|
description: |
|
||||||
|
Creates quote and executes a single payment in one call (request must include `intent`). For
|
||||||
|
raw `card` destinations, execution requires `exp_month` and `exp_year`; `cardToken`
|
||||||
|
destinations only require `token`. Card-recipient AML screening occurs during execution.
|
||||||
|
An unchanged payment reuses its persisted compliance decision on idempotent execution replay,
|
||||||
|
avoiding a duplicate AML call. A definitive denial terminates the payment with public
|
||||||
|
`failureCode: failure_restriction` and `failureReason: aml_denied`.
|
||||||
|
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
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: List payments in organization
|
||||||
|
description: |
|
||||||
|
Returns organization payments with cursor pagination and optional filters.
|
||||||
|
State filters accept aliases (`accepted`, `settled`, `failed`, etc.) or canonical orchestration states.
|
||||||
|
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
|
||||||
|
description: Filter by quotation reference used for execution.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: quote_ref
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Alias of `quotation_ref`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: created_from
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Include payments created at or after this RFC3339 timestamp.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
- name: createdFrom
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Alias of `created_from`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
- name: created_to
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Include payments created before this RFC3339 timestamp (must be after `created_from`).
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
- name: createdTo
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Alias of `created_to`.
|
||||||
|
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
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Quote multiple payment intents
|
||||||
|
description: |
|
||||||
|
Calculates a batch quote for multiple payment intents in one request. Each item includes
|
||||||
|
`executable`, `state`, and optional `blockReason` so callers can skip blocked items. Raw
|
||||||
|
`card` destinations can omit expiry while quoting, but quoted items intended for later
|
||||||
|
execution should include `exp_month` and `exp_year`. Card-recipient AML screening is not
|
||||||
|
performed during quotation; it runs during payment execution, so an executable quote does
|
||||||
|
not guarantee AML acceptance.
|
||||||
|
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
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Get payment by reference
|
||||||
|
description: Returns a single payment by `payments_ref`.
|
||||||
|
operationId: paymentsGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/payments_ref.yaml#/components/parameters/PaymentsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Payment data
|
||||||
|
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
|
||||||
|
'404':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/NotFound
|
||||||
|
'500':
|
||||||
|
$ref: ../response/operation.yaml#/components/responses/InternalServerError
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Quote single payment intent
|
||||||
|
description: |
|
||||||
|
Calculates quote for one payment intent without executing payment. The response includes
|
||||||
|
`quote.executable`, `quote.state`, and optional `quote.blockReason` so clients can reject
|
||||||
|
non-executable quotes before attempting execution. Raw `card` destinations can omit expiry
|
||||||
|
while quoting, but quotes intended for later execution should include `exp_month` and
|
||||||
|
`exp_year`. Card-recipient AML screening is not performed during quotation; it runs during
|
||||||
|
payment execution, so an executable quote does not guarantee AML acceptance.
|
||||||
|
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
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Get discovery registry snapshot for payments dependencies
|
||||||
|
description: Returns the latest discovery lookup payload used by payments integrations.
|
||||||
|
operationId: paymentsRegistryList
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Discovery registry payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
'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
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
get:
|
||||||
|
tags: [Payments]
|
||||||
|
summary: Get latest discovery refresh event for payments dependencies
|
||||||
|
description: Returns the latest refresh event consumed by the payments API.
|
||||||
|
operationId: paymentsRegistryRefreshGet
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Discovery refresh payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type:
|
||||||
|
- object
|
||||||
|
- 'null'
|
||||||
|
additionalProperties: true
|
||||||
|
'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
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PaymentBase:
|
||||||
|
description: Base fields shared by payment initiation request payloads.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
properties:
|
||||||
|
idempotencyKey:
|
||||||
|
description: Client-supplied key used to safely deduplicate requests.
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
description: Optional request metadata forwarded through payment processing.
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
QuotePaymentRequest:
|
||||||
|
description: |
|
||||||
|
Request payload to quote a single payment intent.
|
||||||
|
For raw `card` destinations, quotation only requires `pan`.
|
||||||
|
If the quoted payment may later be executed, include `exp_month` and `exp_year` during quotation because execution reuses the quoted endpoint snapshot.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- intent
|
||||||
|
properties:
|
||||||
|
idempotencyKey:
|
||||||
|
description: Idempotency key used when persisting quote context.
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
description: Optional metadata associated with the quote request.
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Optional caller-side payment correlation reference to persist with the quote and reuse during execution when the execute request omits it.
|
||||||
|
type: string
|
||||||
|
intent:
|
||||||
|
description: Payment intent to be priced. See `PaymentIntent.destination` for raw-card quote versus execution requirements.
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent
|
||||||
|
previewOnly:
|
||||||
|
description: If true, returns a preview quote without requiring idempotency.
|
||||||
|
type: boolean
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
previewOnly:
|
||||||
|
const: true
|
||||||
|
required:
|
||||||
|
- previewOnly
|
||||||
|
then:
|
||||||
|
not:
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
else:
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
|
||||||
|
QuotePaymentsRequest:
|
||||||
|
description: |
|
||||||
|
Request payload to quote multiple payment intents in a single call.
|
||||||
|
For raw `card` destinations, quotation only requires `pan`.
|
||||||
|
If quoted items may later be executed, include `exp_month` and `exp_year` during quotation because execution reuses the quoted endpoint snapshot.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- intents
|
||||||
|
properties:
|
||||||
|
idempotencyKey:
|
||||||
|
description: Idempotency key used when persisting batch quote context.
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
description: Optional metadata associated with the quote request.
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Optional caller-side batch payment correlation reference to persist with the quote and reuse during execution when the execute request omits it.
|
||||||
|
type: string
|
||||||
|
intents:
|
||||||
|
description: List of payment intents to be priced. See each intent destination for raw-card quote versus execution requirements.
|
||||||
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent
|
||||||
|
previewOnly:
|
||||||
|
description: If true, returns preview quotes without requiring idempotency.
|
||||||
|
type: boolean
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
previewOnly:
|
||||||
|
const: true
|
||||||
|
required:
|
||||||
|
- previewOnly
|
||||||
|
then:
|
||||||
|
not:
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
else:
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
|
||||||
|
InitiatePaymentRequest:
|
||||||
|
description: |
|
||||||
|
Request payload to initiate a single payment.
|
||||||
|
When executing a raw `card` destination from inline `intent`, `pan`, `exp_month`, and `exp_year` must be present.
|
||||||
|
When executing a `cardToken` destination, only `token` is required by current logic.
|
||||||
|
allOf:
|
||||||
|
- $ref: ./payment.yaml#/components/schemas/PaymentBase
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
|
oneOf:
|
||||||
|
- required: [intent]
|
||||||
|
- required: [quoteRef]
|
||||||
|
properties:
|
||||||
|
intent:
|
||||||
|
description: Payment intent to execute directly. Raw `card` destinations require expiry at execution time.
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentIntent
|
||||||
|
quoteRef:
|
||||||
|
description: Reference to a previously generated quote to execute. If that quote contains a raw `card` destination, the original quote must already include `exp_month` and `exp_year`.
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Optional caller-side payment correlation reference. When omitted, execution may reuse the value stored with the quote.
|
||||||
|
type: string
|
||||||
|
|
||||||
|
InitiatePaymentsRequest:
|
||||||
|
description: |
|
||||||
|
Request payload to initiate multiple payments from a multi-quote reference.
|
||||||
|
If any quoted item contains a raw `card` destination, that item's original quote must already include `exp_month` and `exp_year`.
|
||||||
|
allOf:
|
||||||
|
- $ref: ./payment.yaml#/components/schemas/PaymentBase
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- quoteRef
|
||||||
|
properties:
|
||||||
|
quoteRef:
|
||||||
|
description: Reference to a previously generated multi-quote. Raw-card items execute from the stored quoted endpoint snapshot.
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Optional caller-side payment correlation reference. When omitted, execution may reuse the value stored with the quote.
|
||||||
|
type: string
|
||||||
|
|
||||||
|
InitiatePaymentByQuoteRequest:
|
||||||
|
description: |
|
||||||
|
Request payload to initiate one payment from an existing quote reference.
|
||||||
|
If the quote contains a raw `card` destination, the original quote must already include `exp_month` and `exp_year`.
|
||||||
|
allOf:
|
||||||
|
- $ref: ./payment.yaml#/components/schemas/PaymentBase
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- quoteRef
|
||||||
|
properties:
|
||||||
|
quoteRef:
|
||||||
|
description: Reference to a previously generated quote to execute. Execution reuses the stored quoted endpoint snapshot.
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Optional caller-side payment correlation reference. When omitted, execution may reuse the value stored with the quote.
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PaymentQuoteData:
|
||||||
|
description: Response payload for a single payment quote.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- quote
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
idempotencyKey:
|
||||||
|
description: Idempotency key associated with the quote response.
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Caller-supplied payment correlation reference echoed from the quote request, when provided.
|
||||||
|
type: string
|
||||||
|
quote:
|
||||||
|
description: Generated quote data for the requested payment intent.
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentQuote
|
||||||
|
|
||||||
|
PaymentQuotesData:
|
||||||
|
description: Response payload for a batch quote request.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- quote
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
quote:
|
||||||
|
description: Batch quote summary and quoted items.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
idempotencyKey:
|
||||||
|
description: Idempotency key associated with the batch quote response.
|
||||||
|
type: string
|
||||||
|
clientPaymentRef:
|
||||||
|
description: Caller-supplied payment correlation reference echoed from the batch quote request, when provided.
|
||||||
|
type: string
|
||||||
|
quoteRef:
|
||||||
|
description: Reference to the generated batch quote.
|
||||||
|
type: string
|
||||||
|
items:
|
||||||
|
description: Collection of quotes for each requested payment intent.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/PaymentQuote
|
||||||
|
|
||||||
|
PaymentsData:
|
||||||
|
description: Response payload containing a list of payments.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- payments
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
payments:
|
||||||
|
description: Collection of payment records.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/Payment
|
||||||
|
page:
|
||||||
|
description: Pagination cursor metadata for payment listing endpoints.
|
||||||
|
$ref: ../../../models/common/pagination.yaml#/components/schemas/CursorPageResponse
|
||||||
|
|
||||||
|
PaymentData:
|
||||||
|
description: Response payload containing a single payment record.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- payment
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
payment:
|
||||||
|
description: Requested payment record.
|
||||||
|
$ref: ../../../models/payment/payment.yaml#/components/schemas/Payment
|
||||||
|
|
||||||
|
FXCurrenciesData:
|
||||||
|
description: Response payload containing the BFF startup-cached Treasury FX currency catalogue projection.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- currencies
|
||||||
|
properties:
|
||||||
|
currencies:
|
||||||
|
description: Client-visible currencies backed by Treasury Currency Catalog metadata.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment/fx_metadata.yaml#/components/schemas/FXCurrency
|
||||||
|
|
||||||
|
FXDirectionsData:
|
||||||
|
description: Response payload containing organization-level directed FX availability.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- directions
|
||||||
|
properties:
|
||||||
|
directions:
|
||||||
|
description: Directions with at least one eligible direction-level route for the organization.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/payment/fx_metadata.yaml#/components/schemas/FXDirection
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
get:
|
||||||
|
tags: [Recipients]
|
||||||
|
summary: Archive/unarchive recipient
|
||||||
|
description: Sets recipient archive state by `recipients_ref` and required `archived` query parameter.
|
||||||
|
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
|
||||||
|
description: Target archive value to set on the recipient.
|
||||||
|
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
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
RecipientCreateBody:
|
||||||
|
description: JSON body containing recipient details for create.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/recipient.yaml#/components/schemas/RecipientCreateRequest
|
||||||
|
|
||||||
|
RecipientUpdateBody:
|
||||||
|
description: JSON body containing recipient details for update.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/recipient.yaml#/components/schemas/RecipientUpdateRequest
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
post:
|
||||||
|
tags: [Recipients]
|
||||||
|
summary: Create recipient
|
||||||
|
description: Creates a recipient inside the organization identified by `org_ref`.
|
||||||
|
operationId: recipientsCreate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/org_ref.yaml#/components/parameters/OrgRef
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/recipient.yaml#/components/requestBodies/RecipientCreateBody
|
||||||
|
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
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
get:
|
||||||
|
tags: [Recipients]
|
||||||
|
summary: List recipients
|
||||||
|
description: |
|
||||||
|
Returns recipients for the specified organization context.
|
||||||
|
Supports offset pagination and optional archive filtering.
|
||||||
|
The route currently includes both `org_ref` and `organizations_ref`; the handler resolves organization context from `org_ref` and ignores `organizations_ref`.
|
||||||
|
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
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
get:
|
||||||
|
tags: [Recipients]
|
||||||
|
summary: Get recipient by reference
|
||||||
|
description: Returns a recipient by `recipients_ref`.
|
||||||
|
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
|
||||||
|
description: Deletes recipient by reference. Use `cascade=true` to remove dependent objects when supported.
|
||||||
|
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
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
RecipientBaseRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: Optional recipient identifier. Required by the current update handler.
|
||||||
|
$ref: ../../../models/objectid.yaml#/components/schemas/ObjectId
|
||||||
|
name:
|
||||||
|
description: Optional human-readable recipient name.
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
description: Optional free-form recipient description.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
email:
|
||||||
|
description: Optional recipient email address.
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
avatarUrl:
|
||||||
|
description: Optional avatar URL.
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
status:
|
||||||
|
description: Optional recipient status. When omitted, current handler behavior falls back to the model zero value (`ready`).
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- ready
|
||||||
|
- registered
|
||||||
|
- notRegistered
|
||||||
|
type:
|
||||||
|
description: Optional recipient type. When omitted, current handler behavior falls back to the model zero value (`internal`).
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- internal
|
||||||
|
- external
|
||||||
|
|
||||||
|
RecipientCreateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to create a recipient.
|
||||||
|
The current create handler does not require any JSON fields beyond a valid object payload; organization context comes from the `org_ref` path parameter.
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/RecipientBaseRequest'
|
||||||
|
|
||||||
|
RecipientUpdateRequest:
|
||||||
|
description: |
|
||||||
|
Request payload used to update a recipient.
|
||||||
|
The current PUT handler targets the record by `id` and then replaces it with the submitted values; omitted fields may therefore be reset to zero values.
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/RecipientBaseRequest'
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
RecipientsAuthData:
|
||||||
|
description: Authenticated response payload containing recipients.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- recipients
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
recipients:
|
||||||
|
description: Collection of recipients available to the authenticated account.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/recipient/recipient.yaml#/components/schemas/Recipient
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
put:
|
||||||
|
tags: [Recipients]
|
||||||
|
summary: Update recipient
|
||||||
|
description: Updates recipient fields from request payload. The current handler requires `id`; omitted fields may be replaced with zero values.
|
||||||
|
operationId: recipientsUpdate
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
requestBody:
|
||||||
|
$ref: ./bodies/recipient.yaml#/components/requestBodies/RecipientUpdateBody
|
||||||
|
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
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
ApiError:
|
||||||
|
description: Standard API error envelope with optional debugging details.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- error
|
||||||
|
- source
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
description: Application-specific numeric error code.
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
error:
|
||||||
|
description: Human-readable error summary.
|
||||||
|
type: string
|
||||||
|
source:
|
||||||
|
description: Component or subsystem that produced the error.
|
||||||
|
type: string
|
||||||
|
details:
|
||||||
|
description: Optional detailed message providing additional failure context.
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
ServiceUnavailable:
|
||||||
|
description: Service unavailable
|
||||||
|
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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
ApiStatus:
|
||||||
|
type: string
|
||||||
|
description: Unified response status used by backend wrappers.
|
||||||
|
enum:
|
||||||
|
- success
|
||||||
|
- processed
|
||||||
|
- error
|
||||||
|
- request
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
VerificationCodeBody:
|
||||||
|
description: JSON payload used to request a new verification code.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/verification.yaml#/components/schemas/VerificationCodeRequest
|
||||||
|
|
||||||
|
VerifyCodeBody:
|
||||||
|
description: JSON payload containing a verification code to validate.
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../request/verification.yaml#/components/schemas/CodeVerificationRequest
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Verification, Auth]
|
||||||
|
summary: Request verification code
|
||||||
|
description: |
|
||||||
|
Creates a verification challenge for the specified purpose/target.
|
||||||
|
For `purpose=login`, request must be authorized with a pending account token.
|
||||||
|
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
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
VerificationCodeRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- purpose
|
||||||
|
properties:
|
||||||
|
purpose:
|
||||||
|
type: string
|
||||||
|
description: Verification purpose, e.g. login.
|
||||||
|
target:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
description: Optional destination override. When omitted, current handler falls back to the authenticated account email/login.
|
||||||
|
idempotencyKey:
|
||||||
|
type: string
|
||||||
|
quoteRef:
|
||||||
|
description: Required when `purpose` is `payout`; omitted for login and other verification purposes.
|
||||||
|
type: string
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
purpose:
|
||||||
|
const: payout
|
||||||
|
required:
|
||||||
|
- purpose
|
||||||
|
then:
|
||||||
|
required:
|
||||||
|
- quoteRef
|
||||||
|
|
||||||
|
CodeVerificationRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- purpose
|
||||||
|
- code
|
||||||
|
properties:
|
||||||
|
purpose:
|
||||||
|
type: string
|
||||||
|
description: Verification purpose, e.g. login.
|
||||||
|
target:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
description: Optional destination override. When omitted, current handler falls back to the authenticated account email/login.
|
||||||
|
idempotencyKey:
|
||||||
|
type: string
|
||||||
|
quoteRef:
|
||||||
|
description: Required when `purpose` is `payout`; omitted for login and other verification purposes.
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
sessionIdentifier:
|
||||||
|
$ref: ../../../models/auth/session_identifier.yaml#/components/schemas/SessionIdentifier
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
purpose:
|
||||||
|
const: login
|
||||||
|
required:
|
||||||
|
- purpose
|
||||||
|
then:
|
||||||
|
required:
|
||||||
|
- sessionIdentifier
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
purpose:
|
||||||
|
const: payout
|
||||||
|
required:
|
||||||
|
- purpose
|
||||||
|
then:
|
||||||
|
required:
|
||||||
|
- quoteRef
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Verification, Auth]
|
||||||
|
summary: Resend verification code
|
||||||
|
description: |
|
||||||
|
Re-issues a verification challenge using the same request shape as `/verification`.
|
||||||
|
Cooldown and retry limits are enforced by backend verification storage policy.
|
||||||
|
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
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
VerificationResponseData:
|
||||||
|
description: Response data returned after requesting a verification code.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- idempotencyKey
|
||||||
|
- ttl_seconds
|
||||||
|
- cooldown_seconds
|
||||||
|
- target
|
||||||
|
properties:
|
||||||
|
idempotencyKey:
|
||||||
|
description: Idempotency key associated with the verification request.
|
||||||
|
type: string
|
||||||
|
ttl_seconds:
|
||||||
|
description: Verification code validity period in seconds.
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
cooldown_seconds:
|
||||||
|
description: Cooldown period before another code can be requested.
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
target:
|
||||||
|
description: Destination where the verification code was sent.
|
||||||
|
type: string
|
||||||
|
quoteRef:
|
||||||
|
description: Payment quote reference echoed for payout verification requests.
|
||||||
|
type: string
|
||||||
|
|
||||||
|
VerifyResultData:
|
||||||
|
description: Result payload returned after code verification succeeds.
|
||||||
|
oneOf:
|
||||||
|
- $ref: ../../accounts/response/auth.yaml#/components/schemas/LoginData
|
||||||
|
- $ref: ../../response/response.yaml#/components/schemas/SuccessResultData
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
post:
|
||||||
|
tags: [Verification, Auth]
|
||||||
|
summary: Verify code and complete pending flow
|
||||||
|
description: |
|
||||||
|
Verifies submitted code and consumes verification token.
|
||||||
|
For login purpose, returns full auth payload (access + refresh tokens); for other purposes returns operation result.
|
||||||
|
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
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
get:
|
||||||
|
tags: [Wallets]
|
||||||
|
summary: List live managed-wallet assets
|
||||||
|
description: |
|
||||||
|
Returns the live wallet asset catalogue currently announced by healthy CRYPTO
|
||||||
|
gateways in discovery. The endpoint is authenticated and authorized by
|
||||||
|
`organizations_ref`, but the returned asset list is gateway-driven rather than
|
||||||
|
organization-customized. Malformed gateway asset announcements are skipped.
|
||||||
|
If discovery is available but no valid wallet assets are currently announced,
|
||||||
|
the response contains an empty `assets` array.
|
||||||
|
operationId: walletAssetsList
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- $ref: ../parameters/organizations_ref.yaml#/components/parameters/OrganizationsRef
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Live managed-wallet asset catalogue
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../response/response.yaml#/components/schemas/BaseResponse
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: ./response/wallet.yaml#/components/schemas/WalletAssetsAuthData
|
||||||
|
'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
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
WalletAssetsAuthData:
|
||||||
|
description: Authenticated response payload containing live wallet assets.
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- accessToken
|
||||||
|
- assets
|
||||||
|
properties:
|
||||||
|
accessToken:
|
||||||
|
description: Refreshed access token to be used in subsequent API calls.
|
||||||
|
$ref: ../../../models/auth/token_data.yaml#/components/schemas/TokenData
|
||||||
|
assets:
|
||||||
|
description: Managed-wallet assets currently announced by healthy CRYPTO gateways.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../models/wallet/wallet_asset.yaml#/components/schemas/WalletAsset
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
ChainNetwork:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- unspecified
|
||||||
|
- ethereum_mainnet
|
||||||
|
- arbitrum_one
|
||||||
|
- tron_mainnet
|
||||||
|
- tron_nile
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
EndpointType:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- paymentMethod
|
||||||
|
- account
|
||||||
|
- recipient
|
||||||
|
- ledger
|
||||||
|
- managedWallet
|
||||||
|
- cryptoAddress
|
||||||
|
- card
|
||||||
|
- cardToken
|
||||||
|
- bankAccount
|
||||||
|
- iban
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
FxSide:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- buy_base_sell_quote
|
||||||
|
- sell_base_buy_quote
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PaymentKind:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- payout
|
||||||
|
- internal_transfer
|
||||||
|
- fx_conversion
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PaymentMethodType:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- iban
|
||||||
|
- card
|
||||||
|
- cardToken
|
||||||
|
- bankAccount
|
||||||
|
- wallet
|
||||||
|
- cryptoAddress
|
||||||
|
- ledger
|
||||||
Loaded 100 of 556 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user