diff --git a/.specify/feature.json b/.specify/feature.json index aee6f97..c1975c5 100644 --- a/.specify/feature.json +++ b/.specify/feature.json @@ -1,3 +1,3 @@ { - "feature_directory": "specs/004-lab-4-auto-registration" + "feature_directory": "specs/005-lab-5-mocking-testing" } diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 5b4f204..0555d43 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,31 +1,49 @@ @@ -125,7 +143,7 @@ Every sample API MUST meet all of the following criteria: good API design. Learners leave with a correct Backstage setup but no intuition for what a well-designed API looks like. Using purposeful examples makes both lessons land simultaneously. -### VIII. Support Experimentation +### VIII. Support Experimentation & Scale Labs MUST be designed to support forking, adaptation, and deviation. Documentation MUST NOT assume users will follow every step exactly as written. @@ -133,10 +151,27 @@ Where users may reasonably substitute tools, configurations, or approaches, the acknowledge this and explain the trade-offs rather than presenting one path as the only path. Verification steps MUST test outcomes, not prescribed implementation details. +Labs MUST also choose technical approaches that can scale to real-world implementation sizes +(as a reference point, 500+ APIs) via configuration and resource-sizing changes rather than a +different architecture. A lab MAY defer building or exercising the at-scale behavior itself — +the lab demo may run against a handful of sample APIs — as long as: (a) the chosen mechanism has +no fundamental scaling ceiling that would force a redesign, and (b) the lab's documentation +identifies what changes (config, not code) between lab-demo scale and a large-scale deployment, +and why. Design choices whose sole purpose is to simplify the lab, and which do not generalize to +a larger scale even in principle, MUST be flagged explicitly as a known lab-only simplification +rather than left implicit. + **Rationale**: Users fork this repository to adapt it to their own needs, teams, and -constraints. A lab that only works when followed to the letter fails the majority of its -audience. Outcome-based verification and acknowledged variation points make labs resilient -to the experimentation that real learning requires. +constraints — including scale far beyond the lab's own small demo. A lab that only works when +followed to the letter fails the majority of its audience; a lab whose only path to real-world +scale is a rewrite fails learners evaluating whether the approach will actually hold up in their +organization. Outcome-based verification and acknowledged variation points make labs resilient to +experimentation; requiring the *mechanism* — not necessarily the lab's exercised scenario — to +scale keeps labs honest about what's a genuine design decision versus a shortcut taken purely for +tutorial simplicity. Lab 4's `autoApiRegistration` design (a persisted scan-state cache and +multi-source config built for 1000+ files/1GB+ repos, though the lab itself exercises only two +small sample files) already established this pattern; this principle codifies that precedent for +all labs going forward. ### IX. Pragmatic Security for Learning Environments @@ -238,4 +273,4 @@ All plan `Constitution Check` gates MUST reference the principles by Roman numer - `yarn dev` does not exist. Use `yarn start` instead. -**Version**: 1.5.0 | **Ratified**: 2026-06-07 | **Last Amended**: 2026-07-04 +**Version**: 1.6.0 | **Ratified**: 2026-06-07 | **Last Amended**: 2026-07-04 diff --git a/CLAUDE.md b/CLAUDE.md index e465dfc..cdde312 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,5 @@ For additional context about technologies to be used, project structure, shell commands, and other important information, read the current plan -at specs/004-lab-4-auto-registration/plan.md +at specs/005-lab-5-mocking-testing/plan.md diff --git a/README.md b/README.md index 79cbc6f..56241b5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Each lab is self-contained, cross-platform (Windows and macOS), and costs nothin | [Lab 2](labs/lab-02-users-roles/) | Users, Roles & API Visibility | Add users, teams, and a custom permission policy; private APIs are visible only to their owning team, shared APIs are visible to everyone | | [Lab 3](labs/lab-03-api-quality/) | API Quality | Add a shared Spectral ruleset, the api-grade quality plugin, and the Spectral linter plugin; API owners and a platform team see detailed quality/lint results, everyone else sees a summary grade | | [Lab 4](labs/lab-04-auto-registration/) | Auto Registration | Auto-discover and register APIs from a Git mono-repo via a custom `EntityProvider`; source owner, lifecycle, and visibility metadata from `x-*` fields in the spec itself | -| Lab 5 *(coming soon)* | Mocking & Testing | Dynamically mock or exercise a test implementation of any registered API, with support for user-supplied non-production credentials | +| [Lab 5](labs/lab-05-mocking-testing/) | Mocking & Testing | Dynamically mock any registered OpenAPI API via a single lazy-loading gateway process, or exercise a real sandbox; pre-filled, overridable non-production credentials | | Lab 6 *(coming soon)* | API Lifecycle Management | Register multiple major versions of an API in parallel; track lifecycle state (development/test/production) and deprecation/retirement per version | | Lab 7 *(coming soon)* | Other Documentation | Add the Thoughtworks Tech Radar plugin; register blips to plot your API landscape | @@ -70,10 +70,15 @@ labs/ │ ├── README.md ← continue here after Lab 2 │ ├── .spectral.yaml ← shared Spectral ruleset used by both quality plugins │ └── catalog/ ← platform team member (eve) added in this lab -└── lab-04-auto-registration/ - ├── README.md ← continue here after Lab 3 - ├── autoApiRegistration.ts ← backend EntityProvider that scans and registers APIs - └── apis/ ← auto-discovered specs, incl. the Scalar Galaxy vendor copy +├── lab-04-auto-registration/ +│ ├── README.md ← continue here after Lab 3 +│ ├── autoApiRegistration.ts ← backend EntityProvider that scans and registers APIs +│ └── apis/ ← auto-discovered specs, incl. the Scalar Galaxy vendor copy +└── lab-05-mocking-testing/ + ├── README.md ← continue here after Lab 4 + └── code/ + ├── scripts/mock-gateway.mjs ← single lazy-loading Prism mock gateway + └── packages/app/src/modules/apiMocking/ ← apiDocsConfigRef override (mock + credentials) ``` --- @@ -86,12 +91,14 @@ backstage-apiportal-lab/ │ ├── lab-01-base-backstage/ │ ├── lab-02-users-roles/ │ ├── lab-03-api-quality/ -│ └── lab-04-auto-registration/ +│ ├── lab-04-auto-registration/ +│ └── lab-05-mocking-testing/ ├── specs/ ← SDD artifacts (spec, plan, tasks per lab) │ ├── 001-lab-1-base-backstage/ │ ├── 002-lab-2-users-roles/ │ ├── 003-lab-3-api-quality/ -│ └── 004-lab-4-auto-registration/ +│ ├── 004-lab-4-auto-registration/ +│ └── 005-lab-5-mocking-testing/ ├── .specify/ ← Speckit configuration and templates ├── GOAL.md ← high-level goals for the full lab series ├── CONTRIBUTING.md ← how to contribute new labs diff --git a/labs/lab-04-auto-registration/apis/galaxy/AccountService-openapi.yaml b/labs/lab-04-auto-registration/apis/galaxy/AccountService-openapi.yaml new file mode 100644 index 0000000..b0d5522 --- /dev/null +++ b/labs/lab-04-auto-registration/apis/galaxy/AccountService-openapi.yaml @@ -0,0 +1,4942 @@ +openapi: 3.1.0 +servers: +- url: https://cal-test.adyen.com/cal/services/Account/v6 +info: + version: '6' + x-publicVersion: true + title: Account API + description: "This API is used for the classic integration. If you are just starting\ + \ your implementation, refer to our [new integration guide](https://docs.adyen.com/adyen-for-platforms-model)\ + \ instead.\n\nThe Account API provides endpoints for managing account-related\ + \ entities on your platform. These related entities include account holders, accounts,\ + \ bank accounts, shareholders, and verification-related documents. The management\ + \ operations include actions such as creation, retrieval, updating, and deletion\ + \ of them.\n\nFor more information, refer to our [documentation](https://docs.adyen.com/classic-platforms).\n\ + ## Authentication\nYour Adyen contact will provide your API credential and an\ + \ API key. To connect to the API, add an `X-API-Key` header with the API key as\ + \ the value, for example:\n\n ```\ncurl\n-H \"Content-Type: application/json\"\ + \ \\\n-H \"X-API-Key: YOUR_API_KEY\" \\\n...\n```\n\nAlternatively, you can use\ + \ the username and password to connect to the API using basic authentication.\ + \ For example:\n\n```\ncurl\n-U \"ws@MarketPlace.YOUR_PLATFORM_ACCOUNT\":\"YOUR_WS_PASSWORD\"\ + \ \\\n-H \"Content-Type: application/json\" \\\n...\n```\nWhen going live, you\ + \ need to generate new web service user credentials to access the [live endpoints](https://docs.adyen.com/development-resources/live-endpoints).\n\ + \n## Versioning\nThe Account API supports [versioning](https://docs.adyen.com/development-resources/versioning)\ + \ using a version suffix in the endpoint URL. This suffix has the following format:\ + \ \"vXX\", where XX is the version number.\n\nFor example:\n```\nhttps://cal-test.adyen.com/cal/services/Account/v6/createAccountHolder\n\ + ```" + termsOfService: https://www.adyen.com/legal/terms-and-conditions + contact: + name: Adyen Developer Experience team + url: https://github.com/Adyen/adyen-openapi +tags: +- name: Account holders +- name: Accounts +- name: Verification +paths: + /checkAccountHolder: + post: + tags: + - Verification + summary: Trigger verification + description: Triggers the verification of an account holder even if the checks + are not yet required for the volume that they are currently processing. + x-addedInVersion: '5' + operationId: post-checkAccountHolder + x-sortIndex: 3 + x-methodName: checkAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-checkAccountHolder-basic' + schema: + $ref: '#/components/schemas/PerformVerificationRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /closeAccount: + post: + tags: + - Accounts + summary: Close an account + description: Closes an account. If an account is closed, you cannot process + transactions, pay out its funds, or reopen it. If payments are made to a closed + account, the payments are sent to your liable account. + operationId: post-closeAccount + x-sortIndex: 3 + x-methodName: closeAccount + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + closeAccount: + $ref: '#/components/examples/post-closeAccount-closeAccount' + schema: + $ref: '#/components/schemas/CloseAccountRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/CloseAccountResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/CloseAccountResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /closeAccountHolder: + post: + tags: + - Account holders + summary: Close an account holder + description: Changes the [status of an account holder](https://docs.adyen.com/classic-platforms/account-holders-and-accounts#account-holder-statuses) + to **Closed**. This state is final. If an account holder is closed, you can't + process transactions, pay out funds, or reopen it. If payments are made to + an account of an account holder with a **Closed** [`status`](https://docs.adyen.com/api-explorer/#/Account/latest/post/getAccountHolder__resParam_verification-accountHolder-checks-status), + the payments are sent to your liable account. + operationId: post-closeAccountHolder + x-sortIndex: 7 + x-methodName: closeAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-closeAccountHolder-basic' + schema: + $ref: '#/components/schemas/CloseAccountHolderRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/CloseAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/CloseAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /closeStores: + post: + tags: + - Account holders + summary: Close stores + description: Closes stores associated with an account holder. + x-addedInVersion: '5' + operationId: post-closeStores + x-sortIndex: 9 + x-methodName: closeStores + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CloseStoresRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /createAccount: + post: + tags: + - Accounts + summary: Create an account + description: Creates an account under an account holder. An account holder can + have [multiple accounts](https://docs.adyen.com/classic-platforms/account-holders-and-accounts#create-additional-accounts). + operationId: post-createAccount + x-sortIndex: 1 + x-methodName: createAccount + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-createAccount-basic' + schema: + $ref: '#/components/schemas/CreateAccountRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAccountResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAccountResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /createAccountHolder: + post: + tags: + - Account holders + summary: Create an account holder + description: Creates an account holder that [represents the sub-merchant's entity](https://docs.adyen.com/classic-platforms/account-structure#your-platform) + in your platform. The details that you need to provide in the request depend + on the sub-merchant's legal entity type. For more information, refer to [Account + holder and accounts](https://docs.adyen.com/classic-platforms/account-holders-and-accounts#legal-entity-types). + operationId: post-createAccountHolder + x-sortIndex: 1 + x-methodName: createAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + business: + $ref: '#/components/examples/post-createAccountHolder-business' + individual: + $ref: '#/components/examples/post-createAccountHolder-individual' + schema: + $ref: '#/components/schemas/CreateAccountHolderRequest' + responses: + '200': + content: + application/json: + examples: + business: + $ref: '#/components/examples/post-createAccountHolder-business-200' + individual: + $ref: '#/components/examples/post-createAccountHolder-individual-200' + schema: + $ref: '#/components/schemas/CreateAccountHolderResponse' + description: OK - the request has succeeded. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /deleteBankAccounts: + post: + tags: + - Verification + summary: Delete bank accounts + description: 'Deletes bank accounts associated with an account holder. ' + operationId: post-deleteBankAccounts + x-sortIndex: 4 + x-methodName: deleteBankAccounts + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-deleteBankAccounts-basic' + schema: + $ref: '#/components/schemas/DeleteBankAccountRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /deleteLegalArrangements: + post: + tags: + - Verification + summary: Delete legal arrangements + description: Deletes legal arrangements and/or legal arrangement entities associated + with an account holder. + operationId: post-deleteLegalArrangements + x-sortIndex: 6 + x-methodName: deleteLegalArrangements + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + arrangements: + $ref: '#/components/examples/post-deleteLegalArrangements-arrangements' + entities: + $ref: '#/components/examples/post-deleteLegalArrangements-entities' + schema: + $ref: '#/components/schemas/DeleteLegalArrangementRequest' + responses: + '200': + content: + application/json: + examples: + arrangements: + $ref: '#/components/examples/post-deleteLegalArrangements-arrangements-200' + entities: + $ref: '#/components/examples/post-deleteLegalArrangements-entities-200' + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + arrangements: + $ref: '#/components/examples/post-deleteLegalArrangements-arrangements-400' + entities: + $ref: '#/components/examples/post-deleteLegalArrangements-entities-400' + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /deletePayoutMethods: + post: + tags: + - Verification + summary: Delete payout methods + description: Deletes payout methods associated with an account holder. + x-addedInVersion: '5' + operationId: post-deletePayoutMethods + x-sortIndex: 5 + x-methodName: deletePayoutMethods + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-deletePayoutMethods-basic' + schema: + $ref: '#/components/schemas/DeletePayoutMethodRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /deleteShareholders: + post: + tags: + - Verification + summary: Delete shareholders + description: Deletes shareholders associated with an account holder. + operationId: post-deleteShareholders + x-sortIndex: 7 + x-methodName: deleteShareholders + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-deleteShareholders-basic' + schema: + $ref: '#/components/schemas/DeleteShareholderRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /deleteSignatories: + post: + tags: + - Verification + summary: Delete signatories + description: Deletes signatories associated with an account holder. + operationId: post-deleteSignatories + x-sortIndex: 8 + x-methodName: deleteSignatories + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DeleteSignatoriesRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /getAccountHolder: + post: + tags: + - Account holders + summary: Get an account holder + description: Returns the details of an account holder. + operationId: post-getAccountHolder + x-sortIndex: 2 + x-methodName: getAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + accountCode: + $ref: '#/components/examples/post-getAccountHolder-accountCode' + accountHolderCode: + $ref: '#/components/examples/post-getAccountHolder-accountHolderCode' + schema: + $ref: '#/components/schemas/GetAccountHolderRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /getTaxForm: + post: + tags: + - Account holders + summary: Get a tax form + description: Generates a tax form for account holders operating in the US. For + more information, refer to [Providing tax forms](https://docs.adyen.com/classic-platforms/tax-forms). + operationId: post-getTaxForm + x-sortIndex: 8 + x-methodName: getTaxForm + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-getTaxForm-basic' + schema: + $ref: '#/components/schemas/GetTaxFormRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetTaxFormResponse' + description: OK - the request has succeeded. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /getUploadedDocuments: + post: + tags: + - Verification + summary: Get documents + description: 'Returns documents that were previously uploaded for an account + holder. Adyen uses the documents during the [verification process](https://docs.adyen.com/classic-platforms/verification-process). + + ' + operationId: post-getUploadedDocuments + x-sortIndex: 2 + x-methodName: getUploadedDocuments + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-getUploadedDocuments-basic' + schema: + $ref: '#/components/schemas/GetUploadedDocumentsRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetUploadedDocumentsResponse' + description: OK - the request has succeeded. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /suspendAccountHolder: + post: + tags: + - Account holders + summary: Suspend an account holder + description: Changes the [status of an account holder](https://docs.adyen.com/classic-platforms/account-holders-and-accounts#account-holder-statuses) + to **Suspended**. + operationId: post-suspendAccountHolder + x-sortIndex: 5 + x-methodName: suspendAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-suspendAccountHolder-basic' + schema: + $ref: '#/components/schemas/SuspendAccountHolderRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/SuspendAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/SuspendAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /unSuspendAccountHolder: + post: + tags: + - Account holders + summary: Unsuspend an account holder + description: "Changes the [status of an account holder](https://docs.adyen.com/classic-platforms/account-holders-and-accounts#account-holder-statuses)\ + \ from **Suspended** to **Inactive**. \nAccount holders can have a **Suspended**\ + \ [`status`](https://docs.adyen.com/api-explorer/#/Account/latest/post/getAccountHolder__resParam_verification-accountHolder-checks-status)\ + \ if you suspend them through the [`/suspendAccountHolder`](https://docs.adyen.com/api-explorer/#/Account/v5/post/suspendAccountHolder)\ + \ endpoint or if a verification deadline expires.\n\nYou can only unsuspend\ + \ account holders if they do not have verification checks with a **FAILED**\ + \ [`status`](https://docs.adyen.com/api-explorer/#/Account/latest/post/getAccountHolder__resParam_verification-accountHolder-checks-status)." + operationId: post-unSuspendAccountHolder + x-sortIndex: 6 + x-methodName: unSuspendAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-unSuspendAccountHolder-basic' + schema: + $ref: '#/components/schemas/UnSuspendAccountHolderRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UnSuspendAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/UnSuspendAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /updateAccount: + post: + tags: + - Accounts + summary: Update an account + description: Updates the description or payout schedule of an account. + operationId: post-updateAccount + x-sortIndex: 2 + x-methodName: updateAccount + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-updateAccount-basic' + schema: + $ref: '#/components/schemas/UpdateAccountRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAccountResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAccountResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /updateAccountHolder: + post: + tags: + - Account holders + summary: Update an account holder + description: "Updates the `accountHolderDetails` and `processingTier` of an\ + \ account holder, and adds bank accounts and shareholders.\n\nWhen updating\ + \ `accountHolderDetails`, parameters that are not included in the request\ + \ are left unchanged except for the following object:\n\n* `metadata`: Updating\ + \ the metadata replaces the entire object. This means that to update an existing\ + \ key-value pair, you must provide the changes, as well as other existing\ + \ key-value pairs.\n\nWhen updating any field in the following objects, you\ + \ must submit all the fields required for validation:\n\n * `address`\n\n\ + * `fullPhoneNumber`\n\n* `bankAccountDetails.BankAccountDetail`\n\n* `businessDetails.shareholders.ShareholderContact`\n\ + \n For example, to update the `address.postalCode`, you must also submit the\ + \ `address.country`, `.city`, `.street`, `.postalCode`, and possibly `.stateOrProvince`\ + \ so that the address can be validated.\n\nTo add a bank account or shareholder,\ + \ provide the bank account or shareholder details without a `bankAccountUUID`\ + \ or a `shareholderCode`.\n\n" + operationId: post-updateAccountHolder + x-sortIndex: 3 + x-methodName: updateAccountHolder + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + addShareholders: + $ref: '#/components/examples/post-updateAccountHolder-addShareholders' + bankAccountDetails: + $ref: '#/components/examples/post-updateAccountHolder-bankAccountDetails' + businessDetails: + $ref: '#/components/examples/post-updateAccountHolder-businessDetails' + general: + $ref: '#/components/examples/post-updateAccountHolder-general' + schema: + $ref: '#/components/schemas/UpdateAccountHolderRequest' + responses: + '200': + content: + application/json: + examples: + addShareholders: + $ref: '#/components/examples/post-updateAccountHolder-addShareholders-200' + bankAccountDetails: + $ref: '#/components/examples/post-updateAccountHolder-bankAccountDetails-200' + businessDetails: + $ref: '#/components/examples/post-updateAccountHolder-businessDetails-200' + general: + $ref: '#/components/examples/post-updateAccountHolder-general-200' + schema: + $ref: '#/components/schemas/UpdateAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /updateAccountHolderState: + post: + tags: + - Account holders + summary: Update payout or processing state + description: Disables or enables the processing or payout state of an account + holder. + operationId: post-updateAccountHolderState + x-sortIndex: 4 + x-methodName: updateAccountHolderState + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-updateAccountHolderState-basic' + schema: + $ref: '#/components/schemas/UpdateAccountHolderStateRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountHolderStatusResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountHolderStatusResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. + /uploadDocument: + post: + tags: + - Verification + summary: Upload a document + description: Uploads a document for an account holder. Adyen uses the documents + during the [verification process](https://docs.adyen.com/classic-platforms/verification-process). + operationId: post-uploadDocument + x-sortIndex: 1 + x-methodName: uploadDocument + security: + - BasicAuth: [] + - ApiKeyAuth: [] + requestBody: + content: + application/json: + examples: + basic: + $ref: '#/components/examples/post-uploadDocument-basic' + schema: + $ref: '#/components/schemas/UploadDocumentRequest' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAccountHolderResponse' + description: OK - the request has succeeded. + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAccountHolderResponse' + description: Accepted - the request has been accepted for processing, but + the processing has not been completed. + '400': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-400' + schema: + $ref: '#/components/schemas/ServiceError' + description: Bad Request - a problem reading or understanding the request. + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unauthorized - authentication required. + '403': + content: + application/json: + examples: + generic: + $ref: '#/components/examples/generic-403' + schema: + $ref: '#/components/schemas/ServiceError' + description: Forbidden - insufficient permissions to process the request. + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Unprocessable Entity - a request validation error. + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + description: Internal Server Error - the server could not process the request. +components: + schemas: + Account: + additionalProperties: false + properties: + accountCode: + description: The code of the account. + type: string + bankAccountUUID: + x-addedInVersion: '5' + description: The bankAccountUUID of the bank account held by the account + holder to couple the account with. Scheduled payouts in currencies matching + the currency of this bank account will be sent to this bank account. Payouts + in different currencies will be sent to a matching bank account of the + account holder. + type: string + beneficiaryAccount: + description: The beneficiary of the account. + type: string + beneficiaryMerchantReference: + description: The reason that a beneficiary has been set up for this account. + This may have been supplied during the setup of a beneficiary at the discretion + of the executing user. + type: string + description: + x-addedInVersion: '4' + description: A description of the account. + type: string + metadata: + x-addedInVersion: '5' + additionalProperties: + type: string + description: 'A set of key and value pairs for general use by the merchant. + + The keys do not have specific names and may be used for storing miscellaneous + data as desired. + + > Note that during an update of metadata, the omission of existing key-value + pairs will result in the deletion of those key-value pairs.' + type: object + payoutMethodCode: + x-addedInVersion: '5' + description: The payout method code held by the account holder to couple + the account with. Scheduled card payouts will be sent using this payout + method code. + type: string + payoutSchedule: + description: The account's payout schedule. + $ref: '#/components/schemas/PayoutScheduleResponse' + payoutSpeed: + x-addedInVersion: '5' + description: 'Speed with which payouts for this account are processed. Permitted + values: `STANDARD`, `SAME_DAY`.' + enum: + - INSTANT + - SAME_DAY + - STANDARD + type: string + status: + x-addedInVersion: '4' + description: 'The status of the account. Possible values: `Active`, `Inactive`, + `Suspended`, `Closed`.' + type: string + type: object + AccountEvent: + additionalProperties: false + properties: + event: + description: 'The event. + + >Permitted values: `InactivateAccount`, `RefundNotPaidOutTransfers`. + + For more information, refer to [Verification checks](https://docs.adyen.com/classic-platforms/verification-process).' + enum: + - InactivateAccount + - RefundNotPaidOutTransfers + type: string + executionDate: + description: The date on which the event will take place. + format: date-time + type: string + reason: + description: The reason why this event has been created. + type: string + type: object + AccountHolderDetails: + additionalProperties: false + properties: + address: + description: The address of the account holder. + $ref: '#/components/schemas/ViasAddress' + bankAccountDetails: + description: Array of bank accounts associated with the account holder. + For details about the required `bankAccountDetail` fields, see [Required + information](https://docs.adyen.com/classic-platforms/verification-process/required-information). + items: + $ref: '#/components/schemas/BankAccountDetail' + type: array + bankAggregatorDataReference: + x-addedInVersion: '5' + description: The opaque reference value returned by the Adyen API during + bank account login. + type: string + businessDetails: + description: 'Details about the business or nonprofit account holder. + + Required when creating an account holder with `legalEntity` **Business** + or **NonProfit**.' + $ref: '#/components/schemas/BusinessDetails' + email: + description: The email address of the account holder. + type: string + fullPhoneNumber: + description: 'The phone number of the account holder provided as a single + string. It will be handled as a landline phone. + + **Examples:** "0031 6 11 22 33 44", "+316/1122-3344", "(0031) 611223344"' + type: string + individualDetails: + description: 'Details about the individual account holder. + + Required when creating an account holder with `legalEntity` **Individual**. + + ' + $ref: '#/components/schemas/IndividualDetails' + lastReviewDate: + description: Date when you last reviewed the account holder's information, + in ISO-8601 YYYY-MM-DD format. For example, **2020-01-31**. + type: string + legalArrangements: + x-addedInVersion: '6' + description: An array containing information about the account holder's + [legal arrangements](https://docs.adyen.com/classic-platforms/verification-process/legal-arrangements). + items: + $ref: '#/components/schemas/LegalArrangementDetail' + type: array + merchantCategoryCode: + description: 'The Merchant Category Code of the account holder. + + > If not specified in the request, this will be derived from the platform + account (which is configured by Adyen).' + type: string + metadata: + additionalProperties: + type: string + description: 'A set of key and value pairs for general use by the account + holder or merchant. + + The keys do not have specific names and may be used for storing miscellaneous + data as desired. + + > The values being stored have a maximum length of eighty (80) characters + and will be truncated if necessary. + + > Note that during an update of metadata, the omission of existing key-value + pairs will result in the deletion of those key-value pairs.' + type: object + payoutMethods: + x-addedInVersion: '5' + description: Array of tokenized card details associated with the account + holder. For details about how you can use the tokens to pay out, refer + to [Pay out to cards](https://docs.adyen.com/classic-platforms/payout-to-cards). + items: + $ref: '#/components/schemas/PayoutMethod' + type: array + phoneNumber: + description: 'The phone number of the account holder. + + > Required if a `fullPhoneNumber` is not provided.' + $ref: '#/components/schemas/ViasPhoneNumber' + principalBusinessAddress: + description: The principal business address of the account holder. + $ref: '#/components/schemas/ViasAddress' + storeDetails: + x-addedInVersion: '5' + description: Array of stores associated with the account holder. Required + when onboarding account holders that have an Adyen [point of sale](https://docs.adyen.com/classic-platforms/platforms-for-pos). + items: + $ref: '#/components/schemas/StoreDetail' + type: array + webAddress: + description: The URL of the website of the account holder. + type: string + required: + - address + type: object + AccountHolderStatus: + additionalProperties: false + properties: + events: + description: A list of events scheduled for the account holder. + items: + $ref: '#/components/schemas/AccountEvent' + type: array + payoutState: + description: The payout state of the account holder. + $ref: '#/components/schemas/AccountPayoutState' + processingState: + description: The processing state of the account holder. + $ref: '#/components/schemas/AccountProcessingState' + status: + description: 'The status of the account holder. + + >Permitted values: `Active`, `Inactive`, `Suspended`, `Closed`.' + enum: + - Active + - Closed + - Inactive + - Suspended + type: string + statusReason: + description: The reason why the status was assigned to the account holder. + type: string + required: + - status + type: object + AccountPayoutState: + additionalProperties: false + properties: + allowPayout: + description: Indicates whether payouts are allowed. This field is the overarching + payout status, and is the aggregate of multiple conditions (e.g., KYC + status, disabled flag, etc). If this field is false, no payouts will be + permitted for any of the account holder's accounts. If this field is true, + payouts will be permitted for any of the account holder's accounts. + type: boolean + disableReason: + description: The reason why payouts (to all of the account holder's accounts) + have been disabled (by the platform). If the `disabled` field is true, + this field can be used to explain why. + type: string + disabled: + description: Indicates whether payouts have been disabled (by the platform) + for all of the account holder's accounts. A platform may enable and disable + this field at their discretion. If this field is true, `allowPayout` will + be false and no payouts will be permitted for any of the account holder's + accounts. If this field is false, `allowPayout` may or may not be enabled, + depending on other factors. + type: boolean + notAllowedReason: + x-addedInVersion: '5' + description: The reason why payouts (to all of the account holder's accounts) + have been disabled (by Adyen). If payouts have been disabled by Adyen, + this field will explain why. If this field is blank, payouts have not + been disabled by Adyen. + type: string + payoutLimit: + description: The maximum amount that payouts are limited to. Only applies + if payouts are allowed but limited. + $ref: '#/components/schemas/Amount' + tierNumber: + x-addedInVersion: '3' + description: The payout tier that the account holder occupies. + format: int32 + type: integer + type: object + AccountProcessingState: + additionalProperties: false + properties: + disableReason: + description: The reason why processing has been disabled. + type: string + disabled: + description: Indicates whether the processing of payments is allowed. + type: boolean + processedFrom: + description: The lower bound of the processing tier (i.e., an account holder + must have processed at least this amount of money in order to be placed + into this tier). + $ref: '#/components/schemas/Amount' + processedTo: + description: The upper bound of the processing tier (i.e., an account holder + must have processed less than this amount of money in order to be placed + into this tier). + $ref: '#/components/schemas/Amount' + tierNumber: + x-addedInVersion: '3' + description: The processing tier that the account holder occupies. + format: int32 + type: integer + type: object + Amount: + additionalProperties: false + properties: + currency: + description: The three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes). + maxLength: 3 + minLength: 3 + type: string + value: + description: The amount of the transaction, in [minor units](https://docs.adyen.com/development-resources/currency-codes). + format: int64 + type: integer + required: + - value + - currency + type: object + BankAccountDetail: + additionalProperties: false + properties: + accountNumber: + description: 'The bank account number (without separators). + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + accountType: + description: 'The type of bank account. + + Only applicable to bank accounts held in the USA. + + The permitted values are: `checking`, `savings`. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + bankAccountName: + description: The name of the bank account. + type: string + bankAccountReference: + x-addedInVersion: '5' + description: Merchant reference to the bank account. + type: string + bankAccountUUID: + description: 'The unique identifier (UUID) of the Bank Account. + + >If, during an account holder create or update request, this field is + left blank (but other fields provided), a new Bank Account will be created + with a procedurally-generated UUID. + + + >If, during an account holder create request, a UUID is provided, the + creation of the Bank Account will fail while the creation of the account + holder will continue. + + + >If, during an account holder update request, a UUID that is not correlated + with an existing Bank Account is provided, the update of the account holder + will fail. + + + >If, during an account holder update request, a UUID that is correlated + with an existing Bank Account is provided, the existing Bank Account will + be updated. + + ' + type: string + bankBicSwift: + description: 'The bank identifier code. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + bankCity: + description: 'The city in which the bank branch is located. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + bankCode: + description: 'The bank code of the banking institution with which the bank + account is registered. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + bankName: + description: 'The name of the banking institution with which the bank account + is held. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + branchCode: + description: 'The branch code of the branch under which the bank account + is registered. The value to be specified in this parameter depends on + the country of the bank account: + + * United States - Routing number + + * United Kingdom - Sort code + + * Germany - Bankleitzahl + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + checkCode: + description: 'The check code of the bank account. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + countryCode: + description: 'The two-letter country code in which the bank account is registered. + + >The permitted country codes are defined in ISO-3166-1 alpha-2 (e.g. ''NL''). + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + currencyCode: + description: 'The currency in which the bank account deals. + + >The permitted currency codes are defined in ISO-4217 (e.g. ''EUR''). + + ' + type: string + iban: + description: 'The international bank account number. + + >The IBAN standard is defined in ISO-13616. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerCity: + description: 'The city of residence of the bank account owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerCountryCode: + description: 'The country code of the country of residence of the bank account + owner. + + >The permitted country codes are defined in ISO-3166-1 alpha-2 (e.g. ''NL''). + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerDateOfBirth: + deprecated: true + description: 'The date of birth of the bank account owner. + + The date should be in ISO-8601 format yyyy-mm-dd (e.g. 2000-01-31).' + type: string + ownerHouseNumberOrName: + description: 'The house name or number of the residence of the bank account + owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerName: + description: 'The name of the bank account owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerNationality: + description: 'The country code of the country of nationality of the bank + account owner. + + >The permitted country codes are defined in ISO-3166-1 alpha-2 (e.g. ''NL''). + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerPostalCode: + description: 'The postal code of the residence of the bank account owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerState: + description: 'The state of residence of the bank account owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + ownerStreet: + description: 'The street name of the residence of the bank account owner. + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + primaryAccount: + description: If set to true, the bank account is a primary account. + type: boolean + taxId: + description: 'The tax ID number. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + urlForVerification: + description: 'The URL to be used for bank account verification. + + This may be generated on bank account creation. + + + >Refer to [Required information](https://docs.adyen.com/classic-platforms/verification-process/required-information) + for details on field requirements.' + type: string + type: object + BusinessDetails: + additionalProperties: false + properties: + doingBusinessAs: + description: The registered name of the company (if it differs from the + legal name of the company). + type: string + legalBusinessName: + description: The legal name of the company. + type: string + listedUltimateParentCompany: + description: Information about the parent public company. Required if the + account holder is 100% owned by a publicly listed company. + items: + $ref: '#/components/schemas/UltimateParentCompany' + type: array + registrationNumber: + x-addedInVersion: '4' + description: The registration number of the company. + type: string + shareholders: + description: Array containing information about individuals associated with + the account holder either through ownership or control. For details about + how you can identify them, refer to [our verification guide](https://docs.adyen.com/classic-platforms/verification-process#identify-ubos). + items: + $ref: '#/components/schemas/ShareholderContact' + type: array + signatories: + description: 'Signatories associated with the company. + + Each array entry should represent one signatory.' + items: + $ref: '#/components/schemas/SignatoryContact' + type: array + stockExchange: + x-addedInVersion: '6' + description: Market Identifier Code (MIC). + type: string + stockNumber: + x-addedInVersion: '6' + description: International Securities Identification Number (ISIN). + type: string + stockTicker: + x-addedInVersion: '6' + description: Stock Ticker symbol. + type: string + taxId: + description: The tax ID of the company. + type: string + type: object + CloseAccountHolderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder to be closed. + type: string + required: + - accountHolderCode + type: object + CloseAccountHolderResponse: + additionalProperties: false + properties: + accountHolderStatus: + description: The new status of the Account Holder. + $ref: '#/components/schemas/AccountHolderStatus' + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + CloseAccountRequest: + additionalProperties: false + properties: + accountCode: + description: The code of account to be closed. + type: string + required: + - accountCode + type: object + CloseAccountResponse: + additionalProperties: false + properties: + accountCode: + x-addedInVersion: '5' + description: The account code of the account that is closed. + type: string + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + status: + x-addedInVersion: '2' + description: 'The new status of the account. + + >Permitted values: `Active`, `Inactive`, `Suspended`, `Closed`.' + enum: + - Active + - Closed + - Inactive + - Suspended + type: string + type: object + CloseStoresRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder. + type: string + stores: + description: List of stores to be closed. + items: + type: string + type: array + required: + - accountHolderCode + - stores + type: object + CreateAccountHolderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: 'Your unique identifier for the prospective account holder. + + The length must be between three (3) and fifty (50) characters long. Only + letters, digits, and hyphens (-) are allowed.' + type: string + accountHolderDetails: + description: The details of the prospective account holder. + $ref: '#/components/schemas/AccountHolderDetails' + createDefaultAccount: + description: 'If set to **true**, an account with the default options is + automatically created for the account holder. + + By default, this field is set to **true**.' + type: boolean + description: + x-addedInVersion: '4' + description: A description of the prospective account holder, maximum 256 + characters. You can use alphanumeric characters (A-Z, a-z, 0-9), white + spaces, and underscores `_`. + type: string + legalEntity: + description: 'The legal entity type of the account holder. This determines + the information that should be provided in the request. + + + Possible values: **Business**, **Individual**, or **NonProfit**. + + + * If set to **Business** or **NonProfit**, then `accountHolderDetails.businessDetails` + must be provided, with at least one entry in the `accountHolderDetails.businessDetails.shareholders` + list. + + + * If set to **Individual**, then `accountHolderDetails.individualDetails` + must be provided.' + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + primaryCurrency: + x-addedInVersion: '4' + deprecated: true + description: The three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes), + with which the prospective account holder primarily deals. + type: string + processingTier: + x-addedInVersion: '3' + description: The starting [processing tier](https://docs.adyen.com/classic-platforms/onboarding-and-verification/precheck-kyc-information) + for the prospective account holder. + format: int32 + type: integer + verificationProfile: + x-addedInVersion: '6' + description: The identifier of the profile that applies to this entity. + type: string + required: + - accountHolderCode + - legalEntity + - accountHolderDetails + type: object + CreateAccountHolderResponse: + additionalProperties: false + properties: + accountCode: + description: The code of a new account created for the account holder. + type: string + accountHolderCode: + description: The code of the new account holder. + type: string + accountHolderDetails: + description: Details of the new account holder. + $ref: '#/components/schemas/AccountHolderDetails' + accountHolderStatus: + x-addedInVersion: '2' + description: The status of the new account holder. + $ref: '#/components/schemas/AccountHolderStatus' + description: + x-addedInVersion: '4' + description: The description of the new account holder. + type: string + invalidFields: + x-addedInVersion: '5' + description: A list of fields that caused the `/createAccountHolder` request + to fail. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + legalEntity: + x-addedInVersion: '4' + description: The type of legal entity of the new account holder. + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + primaryCurrency: + x-addedInVersion: '5' + deprecated: true + description: The three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes), + with which the prospective account holder primarily deals. + type: string + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + verification: + x-addedInVersion: '2' + description: The details of KYC Verification of the account holder. + $ref: '#/components/schemas/KYCVerificationResult' + verificationProfile: + x-addedInVersion: '6' + description: The identifier of the profile that applies to this entity. + type: string + type: object + CreateAccountRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of Account Holder under which to create the account. + type: string + bankAccountUUID: + x-addedInVersion: '5' + description: The bankAccountUUID of the bank account held by the account + holder to couple the account with. Scheduled payouts in currencies matching + the currency of this bank account will be sent to this bank account. Payouts + in different currencies will be sent to a matching bank account of the + account holder. + type: string + description: + x-addedInVersion: '4' + description: A description of the account, maximum 256 characters. You can + use alphanumeric characters (A-Z, a-z, 0-9), white spaces, and underscores + `_`. + type: string + metadata: + x-addedInVersion: '5' + additionalProperties: + type: string + description: 'A set of key and value pairs for general use by the merchant. + + The keys do not have specific names and may be used for storing miscellaneous + data as desired. + + > Note that during an update of metadata, the omission of existing key-value + pairs will result in the deletion of those key-value pairs.' + type: object + payoutMethodCode: + x-addedInVersion: '5' + description: The payout method code held by the account holder to couple + the account with. Scheduled card payouts will be sent using this payout + method code. + type: string + payoutSchedule: + description: 'The payout schedule for the account. + + + Possible values: `DEFAULT`, `DAILY`, `DAILY_US`, `DAILY_EU`, `DAILY_AU`, + `DAILY_SG`, `WEEKLY`, `WEEKLY_ON_TUE_FRI_MIDNIGHT`, `BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT`, + `MONTHLY`, `HOLD`. + + > `HOLD` prevents scheduled payouts, but you can still initiate payouts + manually.' + enum: + - BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT + - DAILY + - DAILY_AU + - DAILY_EU + - DAILY_SG + - DAILY_US + - HOLD + - MONTHLY + - WEEKLY + - WEEKLY_MON_TO_FRI_AU + - WEEKLY_MON_TO_FRI_EU + - WEEKLY_MON_TO_FRI_US + - WEEKLY_ON_TUE_FRI_MIDNIGHT + - WEEKLY_SUN_TO_THU_AU + - WEEKLY_SUN_TO_THU_US + type: string + payoutScheduleReason: + description: 'The reason for the payout schedule choice. + + > This field is required when the `payoutSchedule` parameter is set to + `HOLD`.' + type: string + payoutSpeed: + x-addedInVersion: '5' + default: STANDARD + description: 'Speed at which payouts for this account are processed. + + + Possible values: `STANDARD` (default), `SAME_DAY`.' + enum: + - INSTANT + - SAME_DAY + - STANDARD + type: string + required: + - accountHolderCode + type: object + CreateAccountResponse: + additionalProperties: false + properties: + accountCode: + description: The code of the new account. + type: string + accountHolderCode: + description: The code of the account holder. + type: string + bankAccountUUID: + x-addedInVersion: '5' + description: The bankAccountUUID of the bank account held by the account + holder to couple the account with. Scheduled payouts in currencies matching + the currency of this bank account will be sent to this bank account. Payouts + in different currencies will be sent to a matching bank account of the + account holder. + type: string + description: + x-addedInVersion: '4' + description: The description of the account. + type: string + invalidFields: + x-addedInVersion: '5' + description: A list of fields that caused the `/createAccount` request to + fail. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + metadata: + x-addedInVersion: '5' + additionalProperties: + type: string + description: A set of key and value pairs containing metadata. + type: object + payoutMethodCode: + x-addedInVersion: '5' + description: The payout method code held by the account holder to couple + the account with. Scheduled card payouts will be sent using this payout + method code. + type: string + payoutSchedule: + description: The details of the payout schedule added to the account. + $ref: '#/components/schemas/PayoutScheduleResponse' + payoutSpeed: + x-addedInVersion: '5' + description: 'Speed with which payouts for this account are processed. Permitted + values: `STANDARD`, `SAME_DAY`.' + enum: + - INSTANT + - SAME_DAY + - STANDARD + type: string + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + status: + x-addedInVersion: '2' + description: 'The status of the account. + + >Permitted values: `Active`.' + enum: + - Active + - Closed + - Inactive + - Suspended + type: string + type: object + DeleteBankAccountRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder from which to delete the Bank + Account(s). + type: string + bankAccountUUIDs: + description: The code(s) of the Bank Accounts to be deleted. + items: + type: string + type: array + required: + - accountHolderCode + - bankAccountUUIDs + type: object + DeleteLegalArrangementRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder. + type: string + legalArrangements: + description: List of legal arrangements. + items: + $ref: '#/components/schemas/LegalArrangementRequest' + type: array + required: + - accountHolderCode + - legalArrangements + type: object + DeletePayoutMethodRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder, from which to delete the payout + methods. + type: string + payoutMethodCodes: + description: The codes of the payout methods to be deleted. + items: + type: string + type: array + required: + - accountHolderCode + - payoutMethodCodes + type: object + DeleteShareholderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder from which to delete the Shareholders. + type: string + shareholderCodes: + description: The code(s) of the Shareholders to be deleted. + items: + type: string + type: array + required: + - accountHolderCode + - shareholderCodes + type: object + DeleteSignatoriesRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder from which to delete the signatories. + type: string + signatoryCodes: + description: Array of codes of the signatories to be deleted. + items: + type: string + type: array + required: + - accountHolderCode + - signatoryCodes + type: object + DocumentDetail: + additionalProperties: false + properties: + accountHolderCode: + x-addedInVersion: '2' + description: The code of account holder, to which the document applies. + type: string + bankAccountUUID: + x-addedInVersion: '2' + description: 'The Adyen-generated [`bankAccountUUID`](https://docs.adyen.com/api-explorer/#/Account/latest/post/createAccountHolder__resParam_accountHolderDetails-bankAccountDetails-bankAccountUUID) + to which the document must be linked. Refer to [Bank account check](https://docs.adyen.com/classic-platforms/verification-checks/bank-account-check#uploading-a-bank-statement) + for details on when a document should be submitted. + + >Required if the `documentType` is **BANK_STATEMENT**, where a document + is being submitted in order to verify a bank account. + + ' + type: string + description: + description: Description of the document. + type: string + documentType: + description: 'The type of the document. Refer to [Verification checks](https://docs.adyen.com/classic-platforms/verification-checks) + for details on when each document type should be submitted and for the + accepted file formats. + + + Permitted values: + + * **BANK_STATEMENT**: A file containing a bank statement or other document + proving ownership of a specific bank account. + + * **COMPANY_REGISTRATION_SCREENING** (Supported from v5 and later): A + file containing a company registration document. + + * **CONSTITUTIONAL_DOCUMENT**: A file containing information about the + account holder''s legal arrangement. + + * **PASSPORT**: A file containing the identity page(s) of a passport. + + * **ID_CARD_FRONT**: A file containing only the front of the ID card. + In order for a document to be usable, both the **ID_CARD_FRONT** and **ID_CARD_BACK** + must be submitted. + + * **ID_CARD_BACK**: A file containing only the back of the ID card. In + order for a document to be usable, both the **ID_CARD_FRONT** and **ID_CARD_BACK** + must be submitted. + + * **DRIVING_LICENCE_FRONT**: A file containing only the front of the driving + licence. In order for a document to be usable, both the **DRIVING_LICENCE_FRONT** + and **DRIVING_LICENCE_BACK** must be submitted. + + * **DRIVING_LICENCE_BACK**: A file containing only the back of the driving + licence. In order for a document to be usable, both the **DRIVING_LICENCE_FRONT** + and **DRIVING_LICENCE_FRONT** must be submitted. + + ' + enum: + - BANK_STATEMENT + - BSN + - COMPANY_REGISTRATION_SCREENING + - CONSTITUTIONAL_DOCUMENT + - DRIVING_LICENCE + - DRIVING_LICENCE_BACK + - DRIVING_LICENCE_FRONT + - ID_CARD + - ID_CARD_BACK + - ID_CARD_FRONT + - PASSPORT + - PROOF_OF_RESIDENCY + - SSN + - SUPPORTING_DOCUMENTS + type: string + filename: + description: Filename of the document. + type: string + legalArrangementCode: + x-addedInVersion: '6' + description: The Adyen-generated [`legalArrangementCode`](https://docs.adyen.com/api-explorer/#/Account/latest/post/createAccountHolder__resParam_accountHolderDetails-legalArrangements-legalArrangementCode) + to which the document must be linked. + type: string + legalArrangementEntityCode: + x-addedInVersion: '6' + description: The Adyen-generated [`legalArrangementEntityCode`](https://docs.adyen.com/api-explorer/#/Account/v6/post/createAccountHolder__resParam_accountHolderDetails-legalArrangements-legalArrangementEntities-legalArrangementEntityCode) to + which the document must be linked. + type: string + shareholderCode: + x-addedInVersion: '2' + description: 'The Adyen-generated [`shareholderCode`](https://docs.adyen.com/api-explorer/#/Account/latest/post/createAccountHolder__resParam_accountHolderDetails-businessDetails-shareholders-shareholderCode) + to which the document must be linked. Refer to [Verification checks](https://docs.adyen.com/classic-platforms/verification-checks) + for details on when a document should be submitted. + + >Required if the account holder has a `legalEntity` of type **Business** + and the `documentType` is either **PASSPORT**, **ID_CARD_FRONT**, **ID_CARD_BACK**, + **DRIVING_LICENCE_FRONT**, or **DRIVING_LICENCE_BACK**. ' + type: string + signatoryCode: + description: The Adyen-generated [`signatoryCode`](https://docs.adyen.com/api-explorer/#/Account/v6/post/createAccountHolder__resParam_accountHolderDetails-businessDetails-signatories-signatoryCode) + to which the document must be linked. + type: string + required: + - documentType + type: object + ErrorFieldType: + additionalProperties: false + properties: + errorCode: + description: The validation error code. + format: int32 + type: integer + errorDescription: + description: A description of the validation error. + type: string + fieldType: + description: The type of error field. + $ref: '#/components/schemas/FieldType' + type: object + FieldType: + additionalProperties: false + properties: + field: + description: The full name of the property. + type: string + fieldName: + description: The type of the field. + enum: + - accountCode + - accountHolderCode + - accountHolderDetails + - accountNumber + - accountStateType + - accountStatus + - accountType + - address + - balanceAccount + - balanceAccountActive + - balanceAccountCode + - balanceAccountId + - bankAccount + - bankAccountCode + - bankAccountName + - bankAccountUUID + - bankBicSwift + - bankCity + - bankCode + - bankName + - bankStatement + - branchCode + - businessContact + - cardToken + - checkCode + - city + - companyRegistration + - constitutionalDocument + - controller + - country + - countryCode + - currency + - currencyCode + - dateOfBirth + - description + - destinationAccountCode + - document + - documentContent + - documentExpirationDate + - documentIssuerCountry + - documentIssuerState + - documentName + - documentNumber + - documentType + - doingBusinessAs + - drivingLicence + - drivingLicenceBack + - drivingLicenceFront + - drivingLicense + - email + - firstName + - formType + - fullPhoneNumber + - gender + - hopWebserviceUser + - houseNumberOrName + - iban + - idCard + - idCardBack + - idCardFront + - idNumber + - identityDocument + - individualDetails + - infix + - jobTitle + - lastName + - lastReviewDate + - legalArrangement + - legalArrangementCode + - legalArrangementEntity + - legalArrangementEntityCode + - legalArrangementLegalForm + - legalArrangementMember + - legalArrangementMembers + - legalArrangementName + - legalArrangementReference + - legalArrangementRegistrationNumber + - legalArrangementTaxNumber + - legalArrangementType + - legalBusinessName + - legalEntity + - legalEntityType + - linkedViasVirtualAccount + - logo + - merchantAccount + - merchantCategoryCode + - merchantHouseNumber + - merchantReference + - microDeposit + - name + - nationality + - originalReference + - ownerCity + - ownerCountryCode + - ownerDateOfBirth + - ownerHouseNumberOrName + - ownerName + - ownerPostalCode + - ownerState + - ownerStreet + - passport + - passportNumber + - payoutMethod + - payoutMethodCode + - payoutSchedule + - pciSelfAssessment + - personalData + - phoneCountryCode + - phoneNumber + - postalCode + - primaryCurrency + - reason + - registrationNumber + - returnUrl + - schedule + - shareholder + - shareholderCode + - shareholderCodeAndSignatoryCode + - shareholderCodeOrSignatoryCode + - shareholderType + - shareholderTypes + - shopperInteraction + - signatory + - signatoryCode + - socialSecurityNumber + - sourceAccountCode + - splitAccount + - splitConfigurationUUID + - splitCurrency + - splitValue + - splits + - stateOrProvince + - status + - stockExchange + - stockNumber + - stockTicker + - store + - storeDetail + - storeName + - storeReference + - street + - taxId + - tier + - tierNumber + - transferCode + - ultimateParentCompany + - ultimateParentCompanyAddressDetails + - ultimateParentCompanyAddressDetailsCountry + - ultimateParentCompanyBusinessDetails + - ultimateParentCompanyBusinessDetailsLegalBusinessName + - ultimateParentCompanyBusinessDetailsRegistrationNumber + - ultimateParentCompanyCode + - ultimateParentCompanyStockExchange + - ultimateParentCompanyStockNumber + - ultimateParentCompanyStockNumberOrStockTicker + - ultimateParentCompanyStockTicker + - unknown + - value + - verificationType + - virtualAccount + - visaNumber + - webAddress + - year + type: string + shareholderCode: + description: The code of the shareholder that the field belongs to. If empty, + the field belongs to an account holder. + type: string + type: object + GenericResponse: + additionalProperties: false + properties: + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + GetAccountHolderRequest: + additionalProperties: false + properties: + accountCode: + description: 'The code of the account of which to retrieve the details. + + > Required if no `accountHolderCode` is provided.' + type: string + accountHolderCode: + description: 'The code of the account holder of which to retrieve the details. + + > Required if no `accountCode` is provided.' + type: string + showDetails: + x-addedInVersion: '4' + description: True if the request should return the account holder details + type: boolean + type: object + GetAccountHolderResponse: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder. + type: string + accountHolderDetails: + description: Details of the account holder. + $ref: '#/components/schemas/AccountHolderDetails' + accountHolderStatus: + x-addedInVersion: '2' + description: The status of the account holder. + $ref: '#/components/schemas/AccountHolderStatus' + accounts: + description: A list of the accounts under the account holder. + items: + $ref: '#/components/schemas/Account' + type: array + description: + x-addedInVersion: '4' + description: The description of the account holder. + type: string + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + legalEntity: + description: The legal entity of the account holder. + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + migrationData: + x-addedInVersion: '5' + description: Details of the account holder migrated to the balance platform. + $ref: '#/components/schemas/MigrationData' + primaryCurrency: + x-addedInVersion: '4' + description: The three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes), + with which the prospective account holder primarily deals. + type: string + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + systemUpToDateTime: + x-addedInVersion: '5' + description: The time that shows how up to date is the information in the + response. + format: date-time + type: string + verification: + x-addedInVersion: '2' + description: The details of KYC Verification of the account holder. + $ref: '#/components/schemas/KYCVerificationResult' + verificationProfile: + x-addedInVersion: '6' + description: The identifier of the profile that applies to this entity. + type: string + type: object + GetAccountHolderStatusResponse: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder. + type: string + accountHolderStatus: + x-addedInVersion: '2' + description: The status of the Account Holder. + $ref: '#/components/schemas/AccountHolderStatus' + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + GetTaxFormRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The account holder code you provided when you created the account + holder. + type: string + formType: + description: Type of the requested tax form. For example, 1099-K. + type: string + year: + description: Applicable tax year in the YYYY format. + format: int32 + type: integer + required: + - accountHolderCode + - formType + - year + type: object + GetTaxFormResponse: + additionalProperties: false + properties: + content: + description: The content of the tax form in the Base64 binary format. + format: byte + type: string + contentType: + description: The content type of the tax form. + type: string + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + GetUploadedDocumentsRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder for which to retrieve the documents. + type: string + bankAccountUUID: + x-addedInVersion: '2' + description: The code of the Bank Account for which to retrieve the documents. + type: string + shareholderCode: + description: The code of the Shareholder for which to retrieve the documents. + type: string + required: + - accountHolderCode + type: object + GetUploadedDocumentsResponse: + additionalProperties: false + properties: + documentDetails: + description: A list of the documents and their details. + items: + $ref: '#/components/schemas/DocumentDetail' + type: array + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + IndividualDetails: + additionalProperties: false + properties: + name: + description: "The name of the individual.\n>Make sure your account holder\ + \ registers using the name shown on their Photo ID. \n Maximum length:\ + \ 80 characters \n Cannot contain numbers. /n Cannot be empty." + $ref: '#/components/schemas/ViasName' + personalData: + description: Personal information of the individual. + $ref: '#/components/schemas/ViasPersonalData' + type: object + KYCCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + type: object + KYCCheckStatusData: + additionalProperties: false + properties: + requiredFields: + description: A list of the fields required for execution of the check. + items: + type: string + type: array + status: + description: 'The status of the check. + + + Possible values: **AWAITING_DATA** , **DATA_PROVIDED**, **FAILED**, **INVALID_DATA**, + **PASSED**, **PENDING**, **RETRY_LIMIT_REACHED**.' + enum: + - AWAITING_DATA + - DATA_PROVIDED + - FAILED + - INVALID_DATA + - PASSED + - PENDING + - PENDING_REVIEW + - RETRY_LIMIT_REACHED + - UNCHECKED + type: string + summary: + description: A summary of the execution of the check. + $ref: '#/components/schemas/KYCCheckSummary' + type: + description: "The type of check.\n\nPossible values:\n\n * **BANK_ACCOUNT_VERIFICATION**:\ + \ Used in v5 and earlier. Replaced by **PAYOUT_METHOD_VERIFICATION** in\ + \ v6 and later.\n\n * **COMPANY_VERIFICATION**\n\n * **CARD_VERIFICATION**\n\ + \n* **IDENTITY_VERIFICATION**\n\n* **LEGAL_ARRANGEMENT_VERIFICATION**\n\ + \n* **NONPROFIT_VERIFICATION**\n\n * **PASSPORT_VERIFICATION**\n\n* **PAYOUT_METHOD_VERIFICATION**:\ + \ Used in v6 and later.\n\n* **PCI_VERIFICATION**" + enum: + - BANK_ACCOUNT_VERIFICATION + - CARD_VERIFICATION + - COMPANY_VERIFICATION + - IDENTITY_VERIFICATION + - LEGAL_ARRANGEMENT_VERIFICATION + - NONPROFIT_VERIFICATION + - PASSPORT_VERIFICATION + - PAYOUT_METHOD_VERIFICATION + - PCI_VERIFICATION + type: string + required: + - type + - status + type: object + KYCCheckSummary: + additionalProperties: false + properties: + kycCheckCode: + x-addedInVersion: '5' + description: The code of the check. For possible values, refer to [Verification + codes](https://docs.adyen.com/classic-platforms/verification-process/verification-codes). + format: int32 + type: integer + kycCheckDescription: + x-addedInVersion: '5' + description: A description of the check. + type: string + type: object + KYCLegalArrangementCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + legalArrangementCode: + description: The unique ID of the legal arrangement to which the check applies. + type: string + type: object + KYCLegalArrangementEntityCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + legalArrangementCode: + description: The unique ID of the legal arrangement to which the entity + belongs. + type: string + legalArrangementEntityCode: + description: The unique ID of the legal arrangement entity to which the + check applies. + type: string + type: object + KYCPayoutMethodCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + payoutMethodCode: + description: The unique ID of the payoput method to which the check applies. + type: string + type: object + KYCShareholderCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + legalArrangementCode: + x-addedInVersion: '6' + description: The unique ID of the legal arrangement to which the shareholder + belongs, if applicable. + type: string + legalArrangementEntityCode: + x-addedInVersion: '6' + description: The unique ID of the legal arrangement entity to which the + shareholder belongs, if applicable. + type: string + shareholderCode: + description: The code of the shareholder to which the check applies. + type: string + type: object + KYCSignatoryCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + signatoryCode: + description: The code of the signatory to which the check applies. + type: string + type: object + KYCUltimateParentCompanyCheckResult: + additionalProperties: false + properties: + checks: + description: A list of the checks and their statuses. + items: + $ref: '#/components/schemas/KYCCheckStatusData' + type: array + ultimateParentCompanyCode: + x-addedInVersion: '6' + description: The code of the Ultimate Parent Company to which the check + applies. + type: string + type: object + KYCVerificationResult: + additionalProperties: false + properties: + accountHolder: + description: The results of the checks on the account holder. + $ref: '#/components/schemas/KYCCheckResult' + legalArrangements: + x-addedInVersion: '6' + description: The results of the checks on the legal arrangements. + items: + $ref: '#/components/schemas/KYCLegalArrangementCheckResult' + type: array + legalArrangementsEntities: + x-addedInVersion: '6' + description: The results of the checks on the legal arrangement entities. + items: + $ref: '#/components/schemas/KYCLegalArrangementEntityCheckResult' + type: array + payoutMethods: + x-addedInVersion: '6' + description: The results of the checks on the payout methods. + items: + $ref: '#/components/schemas/KYCPayoutMethodCheckResult' + type: array + shareholders: + description: The results of the checks on the shareholders. + items: + $ref: '#/components/schemas/KYCShareholderCheckResult' + type: array + signatories: + description: The results of the checks on the signatories. + items: + $ref: '#/components/schemas/KYCSignatoryCheckResult' + type: array + ultimateParentCompany: + x-addedInVersion: '6' + description: The result of the check on the Ultimate Parent Company. + items: + $ref: '#/components/schemas/KYCUltimateParentCompanyCheckResult' + type: array + type: object + LegalArrangementDetail: + additionalProperties: false + properties: + address: + description: The address of the legal arrangement. + $ref: '#/components/schemas/ViasAddress' + legalArrangementCode: + description: 'Adyen-generated unique alphanumeric identifier (UUID) for + the entry, returned in the response when you create a legal arrangement. + + Use only when updating an account holder. If you include this field when + creating an account holder, the request will fail.' + type: string + legalArrangementEntities: + description: An array containing information about other entities that are + part of the legal arrangement. + items: + $ref: '#/components/schemas/LegalArrangementEntityDetail' + type: array + legalArrangementReference: + description: Your reference for the legal arrangement. Must be between 3 + to 128 characters. + type: string + legalForm: + description: 'The form of legal arrangement. Required if `type` is **Trust** + or **Partnership**. + + + The possible values depend on the `type`. + + + - For `type` **Trust**: **CashManagementTrust**, **CorporateUnitTrust**, + **DeceasedEstate**, **DiscretionaryInvestmentTrust**, **DiscretionaryServicesManagementTrust**, + **DiscretionaryTradingTrust**, **FirstHomeSaverAccountsTrust**, **FixedTrust**, + **FixedUnitTrust**, **HybridTrust**, **ListedPublicUnitTrust**, **OtherTrust**, + **PooledSuperannuationTrust**, **PublicTradingTrust**, or **UnlistedPublicUnitTrust**. + + + - For `type` **Partnership**: **LimitedPartnership**, **FamilyPartnership**, + or **OtherPartnership**' + enum: + - CashManagementTrust + - CorporateUnitTrust + - DeceasedEstate + - DiscretionaryInvestmentTrust + - DiscretionaryServicesManagementTrust + - DiscretionaryTradingTrust + - FirstHomeSaverAccountsTrust + - FixedTrust + - FixedUnitTrust + - HybridTrust + - ListedPublicUnitTrust + - OtherTrust + - PooledSuperannuationTrust + - PublicTradingTrust + - UnlistedPublicUnitTrust + - LimitedPartnership + - FamilyPartnership + - OtherPartnership + type: string + name: + description: 'The legal name of the legal arrangement. Minimum length: 3 + characters.' + type: string + registrationNumber: + description: The registration number of the legal arrangement. + type: string + taxNumber: + description: The tax identification number of the legal arrangement. + type: string + type: + description: "The [type of legal arrangement](https://docs.adyen.com/classic-platforms/verification-process/legal-arrangements#types-of-legal-arrangements).\n\ + \nPossible values:\n\n- **Association** \n\n- **Partnership** \n\n- **SoleProprietorship**\ + \ \n\n- **Trust** \n\n" + enum: + - Association + - Partnership + - SoleProprietorship + - Trust + type: string + required: + - type + - name + - address + type: object + LegalArrangementEntityDetail: + additionalProperties: false + properties: + address: + description: The address of the entity. + $ref: '#/components/schemas/ViasAddress' + businessDetails: + description: Required when creating an entity with `legalEntityType` **Business**, + **NonProfit**, **PublicCompany**, or **Partnership**. + $ref: '#/components/schemas/BusinessDetails' + email: + description: The e-mail address of the entity. + type: string + fullPhoneNumber: + description: 'The phone number of the contact provided as a single string. It + will be handled as a landline phone. + + **Examples:** "0031 6 11 22 33 44", "+316/1122-3344", "(0031) 611223344"' + type: string + individualDetails: + description: Required when creating an entity with `legalEntityType` **Individual**. + $ref: '#/components/schemas/IndividualDetails' + legalArrangementEntityCode: + description: 'Adyen-generated unique alphanumeric identifier (UUID) for + the entry, returned in the response when you create a legal arrangement + entity. + + Use only when updating an account holder. If you include this field when + creating an account holder, the request will fail.' + type: string + legalArrangementEntityReference: + description: Your reference for the legal arrangement entity. + type: string + legalArrangementMembers: + description: 'An array containing the roles of the entity in the legal arrangement. + + + The possible values depend on the legal arrangement `type`. + + + - For `type` **Association**: **ControllingPerson** and **Shareholder**. + + + - For `type` **Partnership**: **Partner** and **Shareholder**. + + + - For `type` **Trust**: **Trustee**, **Settlor**, **Protector**, **Beneficiary**, and + **Shareholder**. + + + ' + items: + enum: + - Beneficiary + - ControllingPerson + - Partner + - Protector + - Settlor + - Shareholder + - Trustee + type: string + type: array + legalEntityType: + description: 'The legal entity type. + + + Possible values: **Business**, **Individual**, **NonProfit**, **PublicCompany**, + or **Partnership**. ' + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + phoneNumber: + description: The phone number of the entity. + $ref: '#/components/schemas/ViasPhoneNumber' + webAddress: + description: The URL of the website of the contact. + type: string + type: object + LegalArrangementRequest: + additionalProperties: false + properties: + legalArrangementCode: + description: The code of the legal arrangement to be deleted. If you also + send `legalArrangementEntityCodes`, only the entities listed will be deleted. + type: string + legalArrangementEntityCodes: + description: List of legal arrangement entities to be deleted. + items: + type: string + type: array + required: + - legalArrangementCode + type: object + MigratedAccounts: + additionalProperties: false + properties: + accountCode: + description: The unique identifier of the account of the migrated account + holder in the classic integration. + type: string + balanceAccountId: + description: The unique identifier of the account of the migrated account + holder in the balance platform. + type: string + type: object + MigratedShareholders: + additionalProperties: false + properties: + legalEntityCode: + description: The unique identifier of the legal entity of that shareholder + in the balance platform. + type: string + shareholderCode: + description: The unique identifier of the account of the migrated shareholder + in the classic integration. + type: string + type: object + MigratedStores: + additionalProperties: false + properties: + businessLineId: + description: The unique identifier of the business line associated with + the migrated account holder in the balance platform. + type: string + storeCode: + description: The unique identifier of the store associated with the migrated + account holder in the classic integration. + type: string + storeId: + description: The unique identifier of the store associated with the migrated + account holder in the balance platform. + type: string + storeReference: + description: Your reference for the store in the classic integration. The + [Customer Area](https://ca-test.adyen.com/) uses this value for the store + description. + type: string + type: object + MigrationData: + additionalProperties: false + properties: + accountHolderId: + description: The unique identifier of the account holder in the balance + platform. + type: string + balancePlatform: + description: The unique identifier of the balance platfrom to which the + account holder was migrated. + type: string + migrated: + description: Set to **true** if the account holder has been migrated. + type: boolean + migratedAccounts: + description: Contains the mapping of virtual account codes (classic integration) + to the balance account codes (balance platform) associated with the migrated + account holder. + items: + $ref: '#/components/schemas/MigratedAccounts' + type: array + migratedShareholders: + description: Contains the mapping of shareholders associated with the migrated + legal entities. + items: + $ref: '#/components/schemas/MigratedShareholders' + type: array + migratedStores: + description: Contains the mapping of business lines and stores associated + with the migrated account holder. + items: + $ref: '#/components/schemas/MigratedStores' + type: array + migrationDate: + description: The date when account holder was migrated. + format: date-time + type: string + type: object + PayoutMethod: + additionalProperties: false + properties: + merchantAccount: + description: The [`merchantAccount`](https://docs.adyen.com/api-explorer/#/CheckoutService/latest/post/payments__reqParam_merchantAccount) + you used in the `/payments` request when you [saved the account holder's + card details](https://docs.adyen.com/classic-platforms/payouts/manual-payout/payout-to-cards#check-and-store). + type: string + payoutMethodCode: + description: Adyen-generated unique alphanumeric identifier (UUID) for the + payout method, returned in the response when you create a payout method. + Required when updating an existing payout method in an `/updateAccountHolder` + request. + type: string + payoutMethodReference: + description: Your reference for the payout method. + type: string + recurringDetailReference: + description: The [`recurringDetailReference`](https://docs.adyen.com/api-explorer/#/CheckoutService/latest/post/payments__resParam_additionalData-ResponseAdditionalDataCommon-recurring-recurringDetailReference) returned + in the `/payments` response when you [saved the account holder's card + details](https://docs.adyen.com/classic-platforms/payouts/manual-payout/payout-to-cards#check-and-store). + type: string + shopperReference: + description: The [`shopperReference`](https://docs.adyen.com/api-explorer/#/CheckoutService/latest/post/payments__reqParam_shopperReference) + you sent in the `/payments` request when you [saved the account holder's + card details](https://docs.adyen.com/classic-platforms/payouts/manual-payout/payout-to-cards#check-and-store). + type: string + required: + - merchantAccount + - shopperReference + - recurringDetailReference + type: object + PayoutScheduleResponse: + additionalProperties: false + properties: + nextScheduledPayout: + description: The date of the next scheduled payout. + format: date-time + type: string + schedule: + description: 'The payout schedule for the account. + + + Possible values: `DEFAULT`, `DAILY`, `DAILY_US`, `DAILY_EU`, `DAILY_AU`, + `DAILY_SG`, `WEEKLY`, `WEEKLY_ON_TUE_FRI_MIDNIGHT`, `BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT`, + `MONTHLY`, `HOLD`. + + > `HOLD` prevents scheduled payouts, but you can still initiate payouts + manually.' + enum: + - BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT + - DAILY + - DAILY_AU + - DAILY_EU + - DAILY_SG + - DAILY_US + - HOLD + - MONTHLY + - WEEKLY + - WEEKLY_MON_TO_FRI_AU + - WEEKLY_MON_TO_FRI_EU + - WEEKLY_MON_TO_FRI_US + - WEEKLY_ON_TUE_FRI_MIDNIGHT + - WEEKLY_SUN_TO_THU_AU + - WEEKLY_SUN_TO_THU_US + type: string + type: object + PerformVerificationRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder to verify. + type: string + accountStateType: + description: 'The state required for the account holder. + + > Permitted values: `Processing`, `Payout`.' + enum: + - LimitedPayout + - LimitedProcessing + - LimitlessPayout + - LimitlessProcessing + - Payout + - Processing + type: string + tier: + description: The tier required for the account holder. + format: int32 + type: integer + required: + - accountHolderCode + - accountStateType + - tier + type: object + PersonalDocumentData: + additionalProperties: false + properties: + expirationDate: + description: "The expiry date of the document, \n in ISO-8601 YYYY-MM-DD\ + \ format. For example, **2000-01-31**." + type: string + issuerCountry: + description: "The country where the document was issued, in the two-character\ + \ \n[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ + \ format. For example, **NL**." + maxLength: 2 + minLength: 2 + type: string + issuerState: + description: The state where the document was issued (if applicable). + type: string + number: + description: The number in the document. + type: string + type: + description: 'The type of the document. Possible values: **ID**, **DRIVINGLICENSE**, + **PASSPORT**, **SOCIALSECURITY**, **VISA**. + + + To delete an existing entry for a document `type`, send only the `type` + field in your request. ' + enum: + - DRIVINGLICENSE + - ID + - PASSPORT + - SOCIALSECURITY + - VISA + type: string + required: + - type + type: object + ServiceError: + additionalProperties: false + properties: + errorCode: + description: The error code mapped to the error message. + type: string + errorType: + description: The category of the error. + type: string + message: + description: A short explanation of the issue. + type: string + pspReference: + description: The PSP reference of the payment. + type: string + status: + description: The HTTP response status. + format: int32 + type: integer + type: object + ShareholderContact: + additionalProperties: false + properties: + address: + description: The address of the person. + $ref: '#/components/schemas/ViasAddress' + email: + description: The e-mail address of the person. + type: string + fullPhoneNumber: + description: 'The phone number of the person provided as a single string. It + will be handled as a landline phone. + + Examples: "0031 6 11 22 33 44", "+316/1122-3344", "(0031) 611223344"' + type: string + jobTitle: + description: 'Job title of the person. Required when the `shareholderType` + is **Controller**. + + + Example values: **Chief Executive Officer**, **Chief Financial Officer**, + **Chief Operating Officer**, **President**, **Vice President**, **Executive + President**, **Managing Member**, **Partner**, **Treasurer**, **Director**, + or **Other**.' + type: string + name: + description: The name of the person. + $ref: '#/components/schemas/ViasName' + personalData: + description: Contains information about the person. + $ref: '#/components/schemas/ViasPersonalData' + phoneNumber: + description: The phone number of the person. + $ref: '#/components/schemas/ViasPhoneNumber' + shareholderCode: + description: 'The unique identifier (UUID) of the shareholder entry. + + >**If, during an Account Holder create or update request, this field is + left blank (but other fields provided), a new Shareholder will be created + with a procedurally-generated UUID.** + + + >**If, during an Account Holder create request, a UUID is provided, the + creation of Account Holder will fail with a validation Error..** + + + >**If, during an Account Holder update request, a UUID that is not correlated + with an existing Shareholder is provided, the update of the Shareholder + will fail.** + + + >**If, during an Account Holder update request, a UUID that is correlated + with an existing Shareholder is provided, the existing Shareholder will + be updated.** + + ' + type: string + shareholderReference: + x-addedInVersion: '5' + description: Your reference for the shareholder entry. + type: string + shareholderType: + description: "Specifies how the person is associated with the account holder.\ + \ \n\nPossible values: \n\n* **Owner**: Individuals who directly or indirectly\ + \ own 25% or more of a company.\n\n* **Controller**: Individuals who are\ + \ members of senior management staff responsible for managing a company\ + \ or organization." + enum: + - Controller + - Owner + - Signatory + type: string + webAddress: + description: The URL of the person's website. + type: string + type: object + SignatoryContact: + additionalProperties: false + properties: + address: + description: The address of the person. + $ref: '#/components/schemas/ViasAddress' + email: + description: The e-mail address of the person. + type: string + fullPhoneNumber: + description: 'The phone number of the person provided as a single string. It + will be handled as a landline phone. + + Examples: "0031 6 11 22 33 44", "+316/1122-3344", "(0031) 611223344"' + type: string + jobTitle: + description: 'Job title of the signatory. + + + Example values: **Chief Executive Officer**, **Chief Financial Officer**, + **Chief Operating Officer**, **President**, **Vice President**, **Executive + President**, **Managing Member**, **Partner**, **Treasurer**, **Director**, + or **Other**.' + type: string + name: + description: The name of the person. + $ref: '#/components/schemas/ViasName' + personalData: + description: Contains information about the person. + $ref: '#/components/schemas/ViasPersonalData' + phoneNumber: + description: The phone number of the person. + $ref: '#/components/schemas/ViasPhoneNumber' + signatoryCode: + description: 'The unique identifier (UUID) of the signatory. + + >**If, during an Account Holder create or update request, this field is + left blank (but other fields provided), a new Signatory will be created + with a procedurally-generated UUID.** + + + >**If, during an Account Holder create request, a UUID is provided, the + creation of the Signatory will fail while the creation of the Account + Holder will continue.** + + + >**If, during an Account Holder update request, a UUID that is not correlated + with an existing Signatory is provided, the update of the Signatory will + fail.** + + + >**If, during an Account Holder update request, a UUID that is correlated + with an existing Signatory is provided, the existing Signatory will be + updated.** + + ' + type: string + signatoryReference: + description: Your reference for the signatory. + type: string + webAddress: + description: The URL of the person's website. + type: string + type: object + StoreDetail: + additionalProperties: false + properties: + address: + description: The address of the physical store where the account holder + will process payments from. + $ref: '#/components/schemas/ViasAddress' + fullPhoneNumber: + description: 'The phone number of the store provided as a single string. It + will be handled as a landline phone. + + + Examples: "0031 6 11 22 33 44", "+316/1122-3344", "(0031) 611223344"' + type: string + logo: + x-addedInVersion: '5' + description: Store logo for payment method setup. + type: string + merchantAccount: + description: The merchant account to which the store belongs. + type: string + merchantCategoryCode: + description: The merchant category code (MCC) that classifies the business + of the account holder. + type: string + merchantHouseNumber: + x-addedInVersion: '5' + description: Merchant house number for payment method setup. + type: string + phoneNumber: + description: The phone number of the store. + $ref: '#/components/schemas/ViasPhoneNumber' + shopperInteraction: + x-addedInVersion: '5' + description: 'The sales channel. Possible values: **Ecommerce**, **POS**.' + enum: + - Ecommerce + - POS + type: string + splitConfigurationUUID: + x-addedInVersion: '5' + description: The unique reference for the split configuration, returned + when you configure splits in your Customer Area. When this is provided, + the `virtualAccount` is also required. Adyen uses the configuration and + the `virtualAccount` to split funds between accounts in your platform. + type: string + status: + description: 'The status of the store. Possible values: **Pending**, **Active**, + **Inactive**, **InactiveWithModifications**, **Closed**.' + enum: + - Active + - Closed + - Inactive + - InactiveWithModifications + - Pending + type: string + store: + description: Adyen-generated unique alphanumeric identifier (UUID) for the + store, returned in the response when you create a store. Required when + updating an existing store in an `/updateAccountHolder` request. + type: string + storeName: + description: "The name of the account holder's store. This value is shown\ + \ in shopper statements.\n\n * Length: Between 3 to 22 characters \n\n\ + \ * The following characters are *not* supported: **:;}{$#@!|<>%^*+=\\\ + \\**\n\n**Note:** storeName does not appear in American Express shopper\ + \ statements by default. Contact Adyen Support to enable this for American\ + \ Express." + type: string + storeReference: + description: "Your unique identifier for the store. The Customer Area also\ + \ uses this value for the store description.\n\n * Length: Between 3 to\ + \ 128 characters\n\n* The following characters are *not* supported: **:;}{$#@!|<>%^*+=\\\ + \\**" + type: string + virtualAccount: + x-addedInVersion: '5' + description: The account holder's `accountCode` where the split amount will + be sent. Required when you provide the `splitConfigurationUUID`. + type: string + webAddress: + x-addedInVersion: '5' + description: URL of the ecommerce store. + type: string + required: + - merchantCategoryCode + - address + - merchantAccount + type: object + SuspendAccountHolderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder to be suspended. + type: string + required: + - accountHolderCode + type: object + SuspendAccountHolderResponse: + additionalProperties: false + properties: + accountHolderStatus: + description: The new status of the Account Holder. + $ref: '#/components/schemas/AccountHolderStatus' + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + UltimateParentCompany: + additionalProperties: false + properties: + address: + description: Address of the ultimate parent company. + $ref: '#/components/schemas/ViasAddress' + businessDetails: + description: Details about the ultimate parent company's business. + $ref: '#/components/schemas/UltimateParentCompanyBusinessDetails' + ultimateParentCompanyCode: + description: Adyen-generated unique alphanumeric identifier (UUID) for the + entry, returned in the response when you create an ultimate parent company. + Required when updating an existing entry in an `/updateAccountHolder` + request. + type: string + type: object + UltimateParentCompanyBusinessDetails: + additionalProperties: false + properties: + legalBusinessName: + description: The legal name of the company. + type: string + registrationNumber: + description: The registration number of the company. + type: string + stockExchange: + description: Market Identifier Code (MIC). + type: string + stockNumber: + description: International Securities Identification Number (ISIN). + type: string + stockTicker: + description: Stock Ticker symbol. + type: string + type: object + UnSuspendAccountHolderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder to be reinstated. + type: string + required: + - accountHolderCode + type: object + UnSuspendAccountHolderResponse: + additionalProperties: false + properties: + accountHolderStatus: + description: The new status of the Account Holder. + $ref: '#/components/schemas/AccountHolderStatus' + invalidFields: + x-addedInVersion: '5' + description: Contains field validation errors that would prevent requests + from being processed. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + type: object + UpdateAccountHolderRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder to be updated. + type: string + accountHolderDetails: + description: 'The details to which the Account Holder should be updated. + + + Required if a processingTier is not provided.' + $ref: '#/components/schemas/AccountHolderDetails' + description: + x-addedInVersion: '4' + description: A description of the account holder, maximum 256 characters. + You can use alphanumeric characters (A-Z, a-z, 0-9), white spaces, and + underscores `_`. + type: string + legalEntity: + x-addedInVersion: '5' + description: 'The legal entity type of the account holder. This determines + the information that should be provided in the request. + + + Possible values: **Business**, **Individual**, or **NonProfit**. + + + * If set to **Business** or **NonProfit**, then `accountHolderDetails.businessDetails` + must be provided, with at least one entry in the `accountHolderDetails.businessDetails.shareholders` + list. + + + * If set to **Individual**, then `accountHolderDetails.individualDetails` + must be provided.' + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + primaryCurrency: + x-addedInVersion: '4' + deprecated: true + description: The primary three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes), + to which the account holder should be updated. + type: string + processingTier: + x-addedInVersion: '3' + description: 'The processing tier to which the Account Holder should be + updated. + + >The processing tier can not be lowered through this request. + + + >Required if accountHolderDetails are not provided.' + format: int32 + type: integer + verificationProfile: + x-addedInVersion: '6' + description: The identifier of the profile that applies to this entity. + type: string + required: + - accountHolderCode + type: object + UpdateAccountHolderResponse: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the account holder. + type: string + accountHolderDetails: + description: Details of the account holder. + $ref: '#/components/schemas/AccountHolderDetails' + accountHolderStatus: + x-addedInVersion: '2' + description: The new status of the account holder. + $ref: '#/components/schemas/AccountHolderStatus' + description: + x-addedInVersion: '4' + description: The description of the account holder. + type: string + invalidFields: + x-addedInVersion: '5' + description: in case the account holder has not been updated, contains account + holder fields, that did not pass the validation. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + legalEntity: + x-addedInVersion: '4' + description: The legal entity of the account holder. + enum: + - Business + - Individual + - NonProfit + - Partnership + - PublicCompany + type: string + primaryCurrency: + x-addedInVersion: '5' + deprecated: true + description: The three-character [ISO currency code](https://docs.adyen.com/development-resources/currency-codes), + with which the prospective account holder primarily deals. + type: string + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + verification: + x-addedInVersion: '2' + description: The details of KYC Verification of the account holder. + $ref: '#/components/schemas/KYCVerificationResult' + verificationProfile: + x-addedInVersion: '6' + description: The identifier of the profile that applies to this entity. + type: string + type: object + UpdateAccountHolderStateRequest: + additionalProperties: false + properties: + accountHolderCode: + description: The code of the Account Holder on which to update the state. + type: string + disable: + description: If true, disable the requested state. If false, enable the + requested state. + type: boolean + reason: + description: 'The reason that the state is being updated. + + >Required if the state is being disabled.' + type: string + stateType: + description: 'The state to be updated. + + >Permitted values are: `Processing`, `Payout`' + enum: + - LimitedPayout + - LimitedProcessing + - LimitlessPayout + - LimitlessProcessing + - Payout + - Processing + type: string + required: + - accountHolderCode + - stateType + - disable + type: object + UpdateAccountRequest: + additionalProperties: false + properties: + accountCode: + description: The code of the account to update. + type: string + bankAccountUUID: + x-addedInVersion: '5' + description: The bankAccountUUID of the bank account held by the account + holder to couple the account with. Scheduled payouts in currencies matching + the currency of this bank account will be sent to this bank account. Payouts + in different currencies will be sent to a matching bank account of the + account holder. + type: string + description: + x-addedInVersion: '4' + description: A description of the account, maximum 256 characters.You can + use alphanumeric characters (A-Z, a-z, 0-9), white spaces, and underscores + `_`. + type: string + metadata: + x-addedInVersion: '5' + additionalProperties: + type: string + description: 'A set of key and value pairs for general use by the merchant. + + The keys do not have specific names and may be used for storing miscellaneous + data as desired. + + > Note that during an update of metadata, the omission of existing key-value + pairs will result in the deletion of those key-value pairs.' + type: object + payoutMethodCode: + x-addedInVersion: '5' + description: The payout method code held by the account holder to couple + the account with. Scheduled card payouts will be sent using this payout + method code. + type: string + payoutSchedule: + description: The details of the payout schedule to which the account must + be updated. + $ref: '#/components/schemas/UpdatePayoutScheduleRequest' + payoutSpeed: + x-addedInVersion: '5' + description: 'Speed at which payouts for this account are processed. + + + Possible values: `STANDARD` (default), `SAME_DAY`.' + enum: + - INSTANT + - SAME_DAY + - STANDARD + type: string + required: + - accountCode + type: object + UpdateAccountResponse: + additionalProperties: false + properties: + accountCode: + description: The code of the account. + type: string + bankAccountUUID: + x-addedInVersion: '5' + description: The bankAccountUUID of the bank account held by the account + holder to couple the account with. Scheduled payouts in currencies matching + the currency of this bank account will be sent to this bank account. Payouts + in different currencies will be sent to a matching bank account of the + account holder. + type: string + description: + x-addedInVersion: '4' + description: The description of the account. + type: string + invalidFields: + x-addedInVersion: '5' + description: A list of fields that caused the `/updateAccount` request to + fail. + items: + $ref: '#/components/schemas/ErrorFieldType' + type: array + metadata: + x-addedInVersion: '5' + additionalProperties: + type: string + description: A set of key and value pairs containing metadata. + type: object + payoutMethodCode: + x-addedInVersion: '5' + description: The payout method code held by the account holder to couple + the account with. Scheduled card payouts will be sent using this payout + method code. + type: string + payoutSchedule: + description: The details of the payout schedule to which the account is + updated. + $ref: '#/components/schemas/PayoutScheduleResponse' + payoutSpeed: + x-addedInVersion: '5' + description: 'Speed at which payouts for this account are processed. + + + Possible values: `STANDARD`, `SAME_DAY`.' + enum: + - INSTANT + - SAME_DAY + - STANDARD + type: string + pspReference: + description: The reference of a request. Can be used to uniquely identify + the request. + type: string + resultCode: + description: The result code. + type: string + required: + - accountCode + type: object + UpdatePayoutScheduleRequest: + additionalProperties: false + properties: + action: + description: 'Direction on how to handle any payouts that have already been + scheduled. + + + Possible values: + + * `CLOSE`: close the existing batch of payouts. + + * `UPDATE`: reschedule the existing batch to the new schedule. + + * `NOTHING` (**default**): allow the payout to proceed.' + enum: + - CLOSE + - NOTHING + - UPDATE + type: string + reason: + description: 'The reason for the payout schedule update. + + > This field is required when the `schedule` parameter is set to `HOLD`.' + type: string + schedule: + description: 'The new payout schedule for the account. + + + Possible values: `DEFAULT`, `DAILY`, `DAILY_US`, `DAILY_EU`, `DAILY_AU`, + `DAILY_SG`, `WEEKLY`, `WEEKLY_ON_TUE_FRI_MIDNIGHT`, `BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT`, + `MONTHLY`, `HOLD`. + + > `HOLD` prevents scheduled payouts, but you can still initiate payouts + manually.' + enum: + - BIWEEKLY_ON_1ST_AND_15TH_AT_MIDNIGHT + - DAILY + - DAILY_AU + - DAILY_EU + - DAILY_SG + - DAILY_US + - HOLD + - MONTHLY + - WEEKLY + - WEEKLY_MON_TO_FRI_AU + - WEEKLY_MON_TO_FRI_EU + - WEEKLY_MON_TO_FRI_US + - WEEKLY_ON_TUE_FRI_MIDNIGHT + - WEEKLY_SUN_TO_THU_AU + - WEEKLY_SUN_TO_THU_US + type: string + required: + - schedule + type: object + UploadDocumentRequest: + additionalProperties: false + properties: + documentContent: + description: 'The content of the document, in Base64-encoded string format. + + + To learn about document requirements, refer to [Verification checks](https://docs.adyen.com/classic-platforms/verification-checks).' + format: byte + type: string + documentDetail: + description: Details of the document being submitted. + $ref: '#/components/schemas/DocumentDetail' + required: + - documentDetail + - documentContent + type: object + ViasAddress: + additionalProperties: false + properties: + city: + description: The name of the city. Required if the `houseNumberOrName`, + `street`, `postalCode`, or `stateOrProvince` are provided. + type: string + country: + description: The two-character country code of the address in ISO-3166-1 + alpha-2 format. For example, **NL**. + type: string + houseNumberOrName: + description: The number or name of the house. + type: string + postalCode: + description: 'The postal code. Required if the `houseNumberOrName`, `street`, + `city`, or `stateOrProvince` are provided. + + + Maximum length: + + + * 5 digits for addresses in the US. + + + * 10 characters for all other countries.' + type: string + stateOrProvince: + description: "The abbreviation of the state or province. Required if the\ + \ `houseNumberOrName`, `street`, `city`, or `postalCode` are provided.\ + \ \n\nMaximum length:\n\n* 2 characters for addresses in the US or Canada.\n\ + \n* 3 characters for all other countries.\n" + type: string + street: + description: The name of the street. Required if the `houseNumberOrName`, + `city`, `postalCode`, or `stateOrProvince` are provided. + type: string + required: + - country + type: object + ViasName: + additionalProperties: false + properties: + firstName: + description: The first name. + maxLength: 80 + type: string + gender: + description: 'The gender. + + >The following values are permitted: `MALE`, `FEMALE`, `UNKNOWN`.' + enum: + - MALE + - FEMALE + - UNKNOWN + maxLength: 1 + type: string + infix: + description: 'The name''s infix, if applicable. + + >A maximum length of twenty (20) characters is imposed.' + maxLength: 20 + type: string + lastName: + description: The last name. + maxLength: 80 + type: string + type: object + ViasPersonalData: + additionalProperties: false + properties: + dateOfBirth: + description: The person's date of birth, in ISO-8601 YYYY-MM-DD format. + For example, **2000-01-31**. + type: string + documentData: + x-addedInVersion: '3' + description: Array that contains information about the person's identification + document. You can submit only one entry per document type. + items: + $ref: '#/components/schemas/PersonalDocumentData' + type: array + nationality: + description: 'The nationality of the person represented by a two-character + country code, in [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + format. For example, **NL**. + + ' + maxLength: 2 + minLength: 2 + type: string + type: object + ViasPhoneNumber: + additionalProperties: false + properties: + phoneCountryCode: + description: 'The two-character country code of the phone number. + + >The permitted country codes are defined in ISO-3166-1 alpha-2 (e.g. ''NL'').' + type: string + phoneNumber: + description: 'The phone number. + + >The inclusion of the phone number country code is not necessary.' + type: string + phoneType: + description: 'The type of the phone number. + + >The following values are permitted: `Landline`, `Mobile`, `SIP`, `Fax`.' + enum: + - Fax + - Landline + - Mobile + - SIP + type: string + type: object + securitySchemes: + ApiKeyAuth: + in: header + name: X-API-Key + type: apiKey + BasicAuth: + scheme: basic + type: http + examples: + generic-400: + summary: Response code 400. Bad Request. + value: + status: 400 + errorCode: '702' + message: 'Unexpected input: I' + errorType: validation + generic-403: + summary: Response code 403. Forbidden. + value: + status: 403 + errorCode: '10_003' + message: Failed to authorize user + errorType: security + post-checkAccountHolder-basic: + summary: Check the account holder. + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + accountStateType: Processing + tier: '2' + post-closeAccount-closeAccount: + summary: Close an account + value: + accountCode: CODE_OF_ACCOUNT + post-closeAccountHolder-basic: + summary: Close an account holder + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + post-createAccount-basic: + summary: Add an account to an account holder + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + post-createAccountHolder-business: + summary: Create business account holder + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + country: US + businessDetails: + doingBusinessAs: Real Good Restaurant + legalBusinessName: Real Good Restaurant Inc. + shareholders: + - shareholderType: Controller + name: + firstName: John + lastName: Carpenter + address: + country: NL + email: testshareholder@email.com + email: test@email.com + webAddress: https://www.your-website.com + legalEntity: Business + post-createAccountHolder-business-200: + summary: Business account holder created + value: + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + country: US + bankAccountDetails: [] + businessDetails: + doingBusinessAs: Real Good Restaurant + legalBusinessName: Real Good Restaurant Inc. + shareholders: + - address: + country: NL + email: testshareholder@email.com + name: + firstName: John + lastName: Carpenter + shareholderCode: SHAREHOLDER_CODE + shareholderType: Controller + email: test@email.com + merchantCategoryCode: MCC_DEFAULT_VALUE + payoutMethods: [] + webAddress: https://www.your-website.com + accountHolderStatus: + status: Active + processingState: + disabled: false + processedFrom: + currency: USD + value: 0 + processedTo: + currency: USD + value: 0 + tierNumber: 0 + payoutState: + allowPayout: true + payoutLimit: + currency: USD + value: 0 + disabled: false + tierNumber: 0 + events: [] + legalEntity: Business + invalidFields: [] + verification: {} + post-createAccountHolder-individual: + summary: Create individual account holder + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + email: tim@green.com + individualDetails: + name: + firstName: Tim + lastName: Green + address: + country: US + webAddress: https://www.your-website.com + legalEntity: Individual + post-createAccountHolder-individual-200: + summary: Individual account holder created + value: + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + country: US + bankAccountDetails: [] + email: tim@green.com + individualDetails: + name: + firstName: Tim + lastName: Green + merchantCategoryCode: '5045' + payoutMethods: [] + webAddress: https://www.your-website.com + accountHolderStatus: + status: Active + processingState: + disabled: false + processedFrom: + currency: USD + value: 0 + processedTo: + currency: USD + value: 0 + tierNumber: 0 + payoutState: + allowPayout: true + payoutLimit: + currency: USD + value: 0 + disabled: false + tierNumber: 0 + events: [] + legalEntity: Individual + invalidFields: [] + verification: {} + post-deleteBankAccounts-basic: + summary: Delete bank accounts + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + bankAccountUUIDs: + - eeb6ed22-3bae-483c-83b9-bc2097a75d40 + post-deleteLegalArrangements-arrangements: + summary: Delete legal arrangements + description: Example request for deleting legal arrangements + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + legalArrangements: + - legalArrangementCode: cdf92f5a-a114-4ce6-8f19-c3f6ec83141c + post-deleteLegalArrangements-arrangements-200: + summary: Legal arrangement deleted + value: + invalidFields: [] + pspReference: '8816080397613514' + post-deleteLegalArrangements-arrangements-400: + summary: Response code 400. Bad Request. + value: + invalidFields: + - errorCode: 34 + errorDescription: An invalid legalArrangementCode code is provided for value + 'cdf92f5a-a114-4ce6-8f19-c3f6ec83141c' + fieldType: + field: AccountHolderDetails.LegalArrangements.legalArrangementCode + fieldName: legalArrangementCode + pspReference: '9916613322577326' + post-deleteLegalArrangements-entities: + summary: Delete legal arrangement entities + description: Example request for deleting legal arrangement entities + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + legalArrangements: + - legalArrangementCode: cdf92f5a-a114-4ce6-8f19-c3f6ec83141c + legalArrangementEntityCodes: + - 755881d3-d6b0-4b34-8ace-1caceb8add63 + post-deleteLegalArrangements-entities-200: + summary: Legal arrangement entities deleted + value: + invalidFields: [] + pspReference: '8816080397613514' + post-deleteLegalArrangements-entities-400: + summary: Response code 400. Bad Request. + value: + invalidFields: + - errorCode: 34 + errorDescription: An invalid legalArrangementEntityCode code is provided + for value 'c92bb932-4867-4cef-bf9d-4ecde37745cf' + fieldType: + field: AccountHolderDetails.LegalArrangements.LegalArrangementsEntities.legalArrangementEntityCode + fieldName: legalArrangementEntityCode + pspReference: '9916613324987358' + post-deletePayoutMethods-basic: + summary: Delete a payout method + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + payoutMethodCodes: + - 34b6ed22-3bae-483c-83b9-bc2097a75d40 + post-deleteShareholders-basic: + summary: Delete shareholders + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + shareholderCodes: + - 9188218c-576e-4cbe-8e86-72722f453920 + post-getAccountHolder-accountCode: + summary: Get an account holder + value: + accountCode: CODE_OF_ACCOUNT + post-getAccountHolder-accountHolderCode: + summary: Get an account holder for the account + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + post-getTaxForm-basic: + summary: Get a tax form + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + formType: 1099-K + year: 2020 + post-getUploadedDocuments-basic: + summary: Get uploaded documents + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + bankAccountUUID: EXAMPLE_UUID + post-suspendAccountHolder-basic: + summary: Suspend an account holder + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + post-unSuspendAccountHolder-basic: + summary: Unsuspend an account holder + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + post-updateAccount-basic: + summary: Set a payout schedule + value: + accountCode: CODE_OF_ACCOUNT + payoutSchedule: + schedule: WEEKLY + action: CLOSE + post-updateAccountHolder-addShareholders: + summary: Add shareholders + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + businessDetails: + shareholders: + - shareholderType: Controller + name: + firstName: Shelly + lastName: Eller + address: + city: San Francisco + country: US + houseNumberOrName: '274' + postalCode: '94107' + stateOrProvince: CA + street: Brannan + email: testshareholder2@email.com + personalData: + dateOfBirth: '1970-01-01' + documentData: + - number: '1234567890' + type: ID + taxId: '123456789' + email: test@email.com + fullPhoneNumber: '+14154890281' + webAddress: http://www.accountholderwebsite.com + post-updateAccountHolder-addShareholders-200: + summary: Shareholders added + value: + invalidFields: [] + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + bankAccountDetails: [] + businessDetails: + shareholders: + - address: + city: San Francisco + country: US + houseNumberOrName: '274' + postalCode: '94107' + stateOrProvince: CA + street: Brannan + email: testshareholder2@email.com + name: + firstName: Shelly + lastName: Eller + personalData: + dateOfBirth: '1970-01-01' + documentData: + - number: '1234567890' + type: ID + shareholderCode: SHAREHOLDER_CODE + shareholderType: Controller + taxId: '123456789' + email: test@email.com + payoutMethods: [] + webAddress: http://www.accountholderwebsite.com + post-updateAccountHolder-bankAccountDetails: + summary: Update bank account details + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + email: tim@green.com + individualDetails: + name: + firstName: Tim + lastName: Green + bankAccountDetails: + - accountNumber: '1678116852' + branchCode: '053101273' + countryCode: US + currencyCode: USD + ownerName: Tim Green + ownerHouseNumberOrName: '100' + ownerStreet: Main Street + ownerPostalCode: 02894 + ownerCity: Springfield + ownerState: AZ + ownerCountryCode: US + post-updateAccountHolder-bankAccountDetails-200: + summary: Bank account details updated + value: + invalidFields: [] + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + country: US + bankAccountDetails: + - accountNumber: '######6852' + bankAccountUUID: BANK_ACCOUNT_UUID + branchCode: '053101273' + countryCode: US + currencyCode: USD + ownerCity: Springfield + ownerCountryCode: US + ownerHouseNumberOrName: '100' + ownerName: Tim Green + ownerPostalCode: 02894 + ownerState: AZ + ownerStreet: Main Street + primaryAccount: false + businessDetails: + doingBusinessAs: Real Good Restaurant + legalBusinessName: Real Good Restaurant Inc. + shareholders: + - address: + country: NL + email: testshareholder@email.com + name: + firstName: John + lastName: Carpenter + shareholderCode: SHAREHOLDER_CODE + shareholderType: Controller + email: tim@green.com + merchantCategoryCode: MCC_DEFAULT_VALUE + payoutMethods: [] + webAddress: https://www.your-website.com + accountHolderStatus: + status: Active + processingState: + disabled: false + processedFrom: + currency: USD + value: 0 + processedTo: + currency: USD + value: 0 + tierNumber: 0 + payoutState: + allowPayout: true + payoutLimit: + currency: USD + value: 0 + disabled: false + tierNumber: 0 + legalEntity: Business + verification: {} + post-updateAccountHolder-businessDetails: + summary: Update business details + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + businessDetails: + shareholders: + - shareholderType: Owner + address: + city: Amsterdam + country: NL + houseNumberOrName: '1' + postalCode: 1111AA + stateOrProvince: NH + street: Main Street + email: testshareholder2@email.com + name: + firstName: Shelly + lastName: Eller + taxId: BV123456789 + email: test@email.com + fullPhoneNumber: '+31612345678' + webAddress: http://www.accountholderwebsite.com + post-updateAccountHolder-businessDetails-200: + summary: Business details updated + value: + invalidFields: [] + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + bankAccountDetails: [] + businessDetails: + shareholders: + - address: + city: Amsterdam + country: NL + houseNumberOrName: '1' + postalCode: 1111AA + stateOrProvince: NH + street: Main Street + email: testshareholder2@email.com + name: + firstName: Shelly + lastName: Eller + shareholderCode: SHAREHOLDER_CODE + shareholderType: Owner + taxId: BV123456789 + email: test@email.com + payoutMethods: [] + webAddress: http://www.accountholderwebsite.com + post-updateAccountHolder-general: + summary: Update individual with documentData property + value: + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + city: NY + country: US + postalCode: '12345' + stateOrProvince: NH + street: Main Street + houseNumberOrName: '100' + email: test@adyen.com + merchantCategoryCode: '7999' + fullPhoneNumber: '+31612345678' + webAddress: http://www.accountholderwebsite.com + post-updateAccountHolder-general-200: + summary: Individual updated with documentData property + value: + invalidFields: [] + pspReference: ALPHANUMERIC_UNIQUE_RESPONSE_REFERENCE + accountHolderCode: YOUR_UNIQUE_ACCOUNT_HOLDER_CODE + accountHolderDetails: + address: + city: NY + country: US + houseNumberOrName: '100' + postalCode: '12345' + stateOrProvince: NH + street: Main Street + bankAccountDetails: [] + businessDetails: + doingBusinessAs: Real Good Restaurant + legalBusinessName: Real Good Restaurant Inc. + shareholders: + - address: + country: NL + email: testshareholder@email.com + name: + firstName: John + lastName: Carpenter + shareholderCode: SHAREHOLDER_CODE + shareholderType: Controller + email: test@adyen.com + merchantCategoryCode: UPDATE_MCC + payoutMethods: [] + phoneNumber: + phoneCountryCode: NL + phoneNumber: '612345678' + phoneType: Landline + webAddress: http://www.accountholderwebsite.com + accountHolderStatus: + status: Active + processingState: + disabled: false + processedFrom: + currency: USD + value: 0 + processedTo: + currency: USD + value: 0 + tierNumber: 0 + payoutState: + allowPayout: true + payoutLimit: + currency: USD + value: 0 + disabled: false + tierNumber: 0 + legalEntity: Business + verification: {} + post-updateAccountHolderState-basic: + summary: Update account holder state + value: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + disable: true + reason: test reason payout + stateType: Payout + post-uploadDocument-basic: + summary: Upload a document + value: + documentContent: dGVzdCBkb2N1bWVudCBjb250ZW50 + documentDetail: + accountHolderCode: CODE_OF_ACCOUNT_HOLDER + documentType: PASSPORT + filename: passport.png + description: test passport description diff --git a/labs/lab-05-mocking-testing/README.md b/labs/lab-05-mocking-testing/README.md new file mode 100644 index 0000000..a1d30a7 --- /dev/null +++ b/labs/lab-05-mocking-testing/README.md @@ -0,0 +1,426 @@ +# Lab 5 — Mocking and Testing + +## Overview + +Every API registered in Labs 1–4 renders a "Try it out" panel — but only if a real backend is +sitting behind the API's declared `servers` URL. Museum's production server +(`https://api.example.museum/v1`) is fictitious and will never resolve; Galaxy's sandbox servers +are real, but not every API a learner (or a real engineer) registers will have one. This lab adds +a locally running, dynamically generated mock to every registered OpenAPI API's page, plus a +documented pattern for APIs that already ship a public sandbox (Galaxy), so "Try it out" always has +something real to talk to. + +By the end of this lab you will have: + +- A single, long-lived mock gateway process (`scripts/mock-gateway.mjs`) that serves mocks for + *every* discovered OpenAPI file on one fixed port, using Stoplight Prism's programmatic library + — not one process per API. It builds a cheap `slug → spec file` map at startup and only parses + and converts a given API's spec the first time that API is actually requested, caching the + result in a bounded LRU map. +- A new frontend module (`packages/app/src/modules/apiMocking/`) that overrides + `apiDocsConfigRef` — the same pattern Lab 3 used for `apiGrade`/`spectralLinter` — to merge a + "Local mock (Lab 5)" server entry into every OpenAPI API's server dropdown, computed purely from + the entity's own name, with zero per-entity configuration. +- A documented, fictional default credential, pre-filled into Swagger UI's own "Authorize" dialog + on page load, so an authenticated request succeeds with zero learner setup — fully editable + through that same dialog if a learner wants to supply their own. + +**What you will learn:** + +- Why a single, lazily-loading gateway process — not one process per API — is the only design that + actually satisfies "works the same at 500+ APIs as it does at 3," and what happens to a + first-draft design that gets this wrong (see "Why one gateway process, not one per API" below) +- Why the API viewer needed a frontend-module override at all — `@backstage/plugin-api-docs` has + no built-in config toggle for extra servers or credential injection +- Why a client-side "Authorize" pre-fill was chosen over a proxy-level header rewrite for the + default credential, and why that choice is what makes "override with your own credential" work + at all +- Why Galaxy needs zero Lab 5 configuration to get a sandbox option, while Museum needs one small + addition to become mockable + +--- + +## Prerequisites + +- **Labs 1–4 completed** — Backstage running locally with Museum, Streetlights, Train Travel, + Galaxy, and the precedence-demo API all registered (Lab 4's auto-registration in place) +- **Node.js 20+ (or 22/24) and Yarn** — same toolchain as Labs 1–4 +- No new external accounts, services, or OS-level prerequisites + +--- + +## Security Note + +This lab introduces the series' first credential: `mocking.defaultCredential`, committed in +`app-config.yaml` as an obviously fictional bearer token (`lab-mock-token-do-not-use`). It exists +purely so a learner can exercise an authenticated request with zero setup — it is pre-filled into +Swagger UI's own "Authorize" dialog (fully visible and editable there), never sent as a hidden, +unconditional header a learner couldn't see or override. + +**Do not follow this pattern in production.** A committed, shared, fictional credential is a +teaching shortcut for a local sandbox with no real data behind it. In a real deployment: + +- Credentials belong in a secrets manager or vault-injected config, never a committed file. +- Credentials should be scoped per user or per team, not shared across everyone who clones the repo. +- A real credential should never be able to reach a real backend from a public or shared + environment — this lab's mock gateway has no real data or side effects to protect in the first + place, which is precisely why a shortcut is acceptable here and nowhere else. + +--- + +## Step 1 — Install Dependencies + +From the Lab 1 Backstage workspace root: + +``` +cd labs/lab-01-base-backstage/backstage +yarn add -D @stoplight/prism-http@5.15.11 @stoplight/http-spec@7.1.0 js-yaml concurrently +``` + +`@stoplight/prism-http` is Stoplight Prism's *programmatic* mock-response library — not the +`prism` CLI. It exposes `createInstance(...).request(...)` as a plain function call that returns a +mocked HTTP response without binding any port of its own, which is what makes a single process +able to serve every API. `@stoplight/http-spec` is pulled in by `prism-http` and used internally to +convert an OpenAPI document into the operation shape Prism consumes. `js-yaml` reads +`app-config.yaml` and each spec file's `info.title`. `concurrently` runs the gateway alongside +`backstage-cli repo start`. + +The frontend module also needs its own copy of `js-yaml`, since it parses +`entity.spec.definition` (always delivered as a raw string) client-side: + +``` +yarn workspace app add js-yaml +``` + +## Step 2 — Add the Mock Gateway Script + +Copy [`code/scripts/mock-gateway.mjs`](code/scripts/mock-gateway.mjs) to +`scripts/mock-gateway.mjs` in the Backstage workspace. At a high level, it: + +1. Reads `app-config.yaml` directly (no Backstage config service — this is a standalone Node + script) for `mocking.gateway.port`/`maxCachedSpecs` and Lab 4's own + `autoApiRegistration.rootPath`/`patterns`. +2. At startup, builds an in-memory `entityNameSlug → specFilePath` map from every file matching + Lab 4's discovery config, **plus** one additional source covering Lab 1's `apis/` directory + (see "Why Museum needs one extra source" below) — a cheap directory walk plus a lightweight + `info.title` read, not the expensive spec-to-operations conversion, so this is safe to do + eagerly even at hundreds of files. +3. On each request to `//*`, looks up the slug, and on a cache miss, converts that one + spec via `@stoplight/prism-http`'s `getHttpOperationsFromSpec(filePath)` — which dereferences + the spec's own internal `$ref`s before converting, a step required for anything beyond the + most trivial spec (see "A correction worth knowing about" below) — caching the result in an + LRU map bounded by `mocking.gateway.maxCachedSpecs`. +4. Calls a single, gateway-lifetime `Prism.createInstance({ mock: { dynamic: false } })` instance's + `.request()` with the translated request and cached operations, and translates the mocked + response back into a real HTTP response. + +### A correction worth knowing about + +The natural first attempt is to `js-yaml`-parse a spec file and hand it directly to +`@stoplight/http-spec`'s `transformOas3Operations(document)`. That works right up until a response +has no static example and Prism falls back to schema-driven generation — at which point it fails +with `Invalid reference token: components`, because `transformOas3Operations` alone does not +resolve the document's own internal `$ref`s (e.g. `#/components/schemas/Foo`), which almost every +non-trivial OpenAPI document has. `getHttpOperationsFromSpec` (exported directly by +`@stoplight/prism-http`) wraps that same call with the dereference step it actually needs — this +was found by testing against Museum's real spec, not by reading documentation more carefully in +advance, which is exactly the kind of thing you only learn by running the code. + +## Step 3 — Add Static Configuration + +Add to `app-config.yaml`: + +```yaml +proxy: + endpoints: + '/mock': + target: 'http://localhost:4010' + changeOrigin: true + credentials: 'dangerously-allow-unauthenticated' + +mocking: + gateway: + port: 4010 + maxCachedSpecs: 100 + defaultCredential: + scheme: bearer + value: lab-mock-token-do-not-use +``` + +The proxy target and `mocking.gateway.port` are the same number, committed twice — Backstage's +`app-config.yaml` has no config-to-config interpolation (only `${ENV_VAR}` substitution), so +keeping them in sync is a one-line manual step, not a recurring one. + +`credentials: 'dangerously-allow-unauthenticated'` is required, not optional: Swagger UI's "Try it +out" issues a plain browser `fetch()`, which never carries a Backstage user/service token. The +proxy plugin's default policy (`require`) demands one on every request, so without this line every +mock request — a learner's included, not just a raw `curl` — gets a `401 Missing credentials` +before it ever reaches the gateway. This is safe specifically because the mock gateway has no real +data or side effects behind it (same justification as the Security Note's shared default +credential below) — do not reach for this setting for a proxy target that fronts anything real. + +## Step 4 — Wire the Start Script + +In the root `package.json`: + +```json +"start": "concurrently -n app,mocks \"backstage-cli repo start\" \"node scripts/mock-gateway.mjs\"" +``` + +No `wait-on` sequencing is needed — the gateway's port and proxy target are static, committed +values valid the moment Backstage starts, whether or not the gateway has finished booting yet; the +gateway only needs to be listening by the time a learner clicks "Try it out". `concurrently`'s +`-k`/`--kill-others` flag is deliberately **not** used: if the gateway process dies or is stopped, +Backstage keeps running and reports a clear connection error on the next mock request (Step 7), +which is exactly the behavior you want to be able to demonstrate and exactly what `-k` would +prevent by tearing down the whole session the moment the gateway exits. + +## Step 5 — Add the `apiMocking` Frontend Module + +Copy [`code/packages/app/src/modules/apiMocking/index.tsx`](code/packages/app/src/modules/apiMocking/index.tsx) +to `packages/app/src/modules/apiMocking/index.tsx`, then register it in `packages/app/src/App.tsx` +alongside Lab 3's modules: + +```ts +import { apiMockingModule } from './modules/apiMocking'; + +export default createApp({ + features: [ + // ...existing features + apiMockingModule, + ], +}); +``` + +The module overrides the `config` extension of the `api-docs` plugin (the same `pluginId` + +extension name the plugin itself registers for `apiDocsConfigRef`) to supply a custom +`getApiDefinitionWidget`. For any `openapi`-type entity, it: + +- Parses `entity.spec.definition` (a raw YAML/JSON string — that's the only form the widget's + `component(definition)` signature ever receives) into an object, appends a + `{ url: '/api/proxy/mock/', description: 'Local mock (Lab 5)' }` entry to + its `servers` array, and passes the merged object through as an extra `spec` prop. +- Reads every `http`/`bearer`-type security scheme the spec declares and pre-authorizes each one + via `onComplete(system) => system.authActions.authorize(...)`, using + `mocking.defaultCredential`. + +Two mechanisms make this possible without any change to `@backstage/plugin-api-docs` itself, +confirmed by reading its source rather than assumed: + +- `getApiDefinitionWidget(apiEntity)` — unlike the widget's own `component(definition)` — receives + the **full** entity, which is what lets this module compute a per-entity mock URL with no + per-entity configuration. +- `OpenApiDefinitionWidget` forwards every prop it receives down to `swagger-ui-react`'s own + ``, *after* its own internal `spec={definitionString}` — so an extra `spec` prop + passed through the widget wins over the string-derived one. + +This new config key also needs to be declared visible to the frontend bundle. Add +`packages/app/config.d.ts`: + +```ts +export interface Config { + mocking?: { + defaultCredential?: { + /** @visibility frontend */ + scheme: string; + /** @visibility frontend */ + value: string; + }; + }; +} +``` + +and add `"configSchema": "config.d.ts"` to `packages/app/package.json`. Without both, Backstage's +config-visibility filter silently strips `mocking.defaultCredential` before it reaches the +browser — `configApi.getOptional(...)` will just return `undefined`, with no error anywhere. This +was found by checking the `